Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typeahead, bloodhound : remote works but not prefetch

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 ?

like image 595
boblemar Avatar asked May 09 '14 16:05

boblemar


3 Answers

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.

like image 93
boblemar Avatar answered Oct 17 '22 04:10

boblemar


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.

like image 10
morizotter Avatar answered Oct 17 '22 05:10

morizotter


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)

like image 2
davew Avatar answered Oct 17 '22 06:10

davew