typeahead, bloodhound : remote works but not prefetch

12,942

Solution 1

Amazingly it worked this morning ! So it drove me to think it was about cache... And it was ! Adding clearPrefetchCache() before initializing bloodhound did the trick.

       bloodHound.clearPrefetchCache();
       bloodHound.initialize();

I think it didn't show any suggestions because it has cached an empty list.

Solution 2

It's because typeahead already loaded your data from prefetch url and stored it in localStorage. At the time data is in localStorage, prefetch is not invoked.

Try change cacheKey prefetch option like below and reload the page. Prefetch will invoke because there is no data tied to the new cacheKey in localStorage.

var engine = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  prefetch: {
    url: "stations.json",
    cacheKey: "change here!"
  }
});

You can also check local storage with chrome developer tools.

enter image description here

Try to delete local storage data and reload page. Prefetch will invoke.

To remove localStorage data before Bloodhound initialization makes its prefetch invoke at every initialization time.

localStorage.removeItem("YOUR CACHEKEY");

// Bloodhound initialization with YOUR CACHEKEY.

clearPrefetchCache() before initialize() is better, I think.

Solution 3

I ran across your question while having issues getting prefetch to work even though remote was working fine. I first worked through caching concerns (since it's been an issue before), but it still wasn't working.

Next I implemented templates in typeahead so I could get some feedback regarding what was happening when I clicked and typed in the field and nothing happened. My notFound template was appearing. This seemed odd since I could see prefetch hit the server. With debug output at the server I could also tell the server was generating the proper json response.

When inspecting the json though I noticed that it had no whitespace and my bloodhound datumTokenizer was configured as Bloodhound.tokenizers.whitespace. This caused me to dig deeper into how the tokenizers are supposed to work.

I found this very helpful: https://github.com/twitter/typeahead.js/blob/master/doc/migration/0.10.0.md#tokenization-methods-must-be-provided

My issue was resolved after switching to:

datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.value);

(where .value is the json property I want to search)

Share:
12,942
boblemar
Author by

boblemar

Updated on June 15, 2022

Comments

  • boblemar
    boblemar almost 2 years

    I want to use prefetch and I can't have it working ! Here is my code :

    function initAutocompletion() {
        $("input[data-autocomplete-prefetch-url]").each(function () {
            var $this = $(this);
        var urlPrefetch = $this.data("autocomplete-prefetch-url");
        var prefetch;
    
        pref = {
            url: urlPrefetch,
            filter: filter
        };
    
        var bloodHound = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            limit: 10,
            prefetch: pref
        });
    
        bloodHound.initialize();
    
        $this
            .typeahead('destroy')
            .typeahead({
                hint: true,
                highlight: true,
                minLength: 1
            },
            {
                displayKey: 'value',
                source: bloodHound.ttAdapter()
            });
        });
     }
    
    function filter(list) {
        return $.map(list, function (v) { return { value: v.toString() }; });
    }
    

    It doesn't work.

    If I use remote instead of prefetch it works !

        var bloodHound = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            limit: 10,
            remote: pref
        });
    

    I can't anderstand.

    Can anyone help me ?

  • Gherman
    Gherman over 9 years
    Official example with prefetch didn't work for me without clearPrefetchCache. Adding clearPrefetchCache before initialize helped. Though it doesn't explain, what's going on.
  • Zachary Dahan
    Zachary Dahan almost 9 years
    .initialize(true) also makes the cache clear each time it's called.
  • Abhinav Kaushal Keshari
    Abhinav Kaushal Keshari almost 9 years
    Probably worth noting that this may not be a great idea for production depending on your app because if you clear the prefetch cache on every page load, you have to reload the data into the cache on every page load so you only get the advantage of the cache until you switch pages or reload the current page. Probably a great idea for a development environment though.
  • Megan Caithlyn
    Megan Caithlyn almost 8 years
    Great info, doesn't provide the solution though.
  • davew
    davew about 7 years
    @Stuffix I don't think so. In my testing environment, I have .initialize(true). If I remove .clearPrefetchCache() from before the initialize, the prefetches stop hitting my server. From my experiments (version 0.11.1), if you want to clear the prefetch cache, you have to call .clearPrefetchCache() before .initialize(true)
  • Zachary Dahan
    Zachary Dahan about 7 years
    @davew you probably right, I wrote this comment 3 years ago so things might have change since. I didn't messed with typeahead since.
  • for_all_intensive_purposes
    for_all_intensive_purposes over 2 years
    Could you please elaborate on tokenizers? We don't understand why they'd differ for prefetch vs remote