Search code examples
knockout.jstypeahead.jsbloodhound

Twitter typeahead with Bloodhound doesn't refresh list with Knockout binding


this may be a tricky one - I'm trying to use the Twitter typeahead with the Bloodhound engine and a custom Knockout binding. In my example, I have two lists of athletes (football and soccer). I'm using a typeahead to select an athlete from one of the lists and I'm using a dropdown to select which list to pull from.

Once a sport is selected from the dropdown, the Bloodhound engine is initialized with the appropriate athletes and the typeahead is created. When the sport is changed, a new Bloodhound engine is created with the new list of athletes. The problem is the typeahead is still using the first list of athletes instead of the new list.

I've debugged through and I know the Bloodhound engine gets recreated with the new list, and then the Twitter typeahead gets the updated source. But alas, the old list comes up when used. I submit this fiddle as evidence - never mind the style, it is a work in progress. To briefly explain the code:

At the top is the AthleteTypeahead class, which the custom athleteTypeahead binding (directly following the class) creates to initialize the suggestion engine and typeahead. At the bottom is my view model, which creates the two different lists of athletes. For debugging and my sanity, I've displayed the full list of selected athletes in view and sent the list to console.log whenever a new Bloodhound suggestion engine is created - both lists update correctly. I've tried calling clear() and clearPrefetchCache() when creating the new engine, even though it's a completely new engine, but no luck there either. Thoughts?


Solution

  • Add $(element).typeahead('destroy') to your AthleteTypeahead constructor, i.e.

    var AthleteTypeahead = function(athletes, element) {
        $(element).typeahead('destroy');
        this.athletes = athletes;
        this.element = element;
    };
    

    You can not create a new typeahead on an element that already has one, you must dispose of the first. You could also save a reference to the bloodhound engine somewhere, and use the clear and add functions to update the engine without the need to destroy and reinitialize the entire typeahead.