ajaxautocompletetypeaheadbloodhound

Typeahead ajax autocomplete is not working


I am trying to make typeahead autocomplete from ajax data, but it's not working.

This is my code.

When I am inspecting from browsers network data, it's correctly getting suggestion data such as below.

http://autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=...&app_code=...&country=USA&mapview=41.382995,-74.301616;41.305715,-74.092278&query=a

{"suggestions":[{"label":"United States Of America, NY, Cornwall, Angola Rd","language":"en","countryCode":"USA","locationId":"NT_7Cpok364jILgH4ksUcyjpC","address":{"country":"United States Of America","state":"NY","county":"Orange","city":"Cornwall","street":"Angola Rd","postalCode":"12518"},"distance":14896,"matchLevel":"street"},{"label":"United States Of America, NY, Garrison, Albany Post Rd","language":"en","countryCode":"USA","locationId":"NT_DM6n2RQmjZ1YvBjMS6MyGA","address":{"country":"United States Of America","state":"NY","county":"Putnam","city":"Garrison","district":"Garrison","street":"Albany Post Rd","postalCode":"10524"},"distance":23981,"matchLevel":"street"},{"label":"United States Of America, NY, Montrose, Albany Post Rd","language":"en","countryCode":"USA","locationId":"NT_NNt..Hu2Z5yXhvu4UpGXwA","address":{"country":"United States Of America","state":"NY","county":"Westchester","city":"Montrose","street":"Albany Post Rd","postalCode":"10548"},"distance":24394,"matchLevel":"street"},{"label":"United States Of America, NY, Croton-on-Hudson, Albany Post Rd","language":"en","countryCode":"USA","locationId":"NT_fokNpGY5GJxSkp195bkloA","address":{"country":"United States Of America","state":"NY","county":"Westchester","city":"Croton-on-Hudson","street":"Albany Post Rd","postalCode":"10520"},"distance":26329,"matchLevel":"street"}]}

But it's not working for autocomplete.

What can I do now?


Solution

  • You need to include the key you want to use to filter objects from the suggestions array in the datumTokenizer method of your Bloodhound instance. Passing in suggestions as an argument for Bloodhound.tokenizers.whitespace would only work if suggestions was an array of strings — the tokenizer expects arguments that it could ultimately resolve to a string tokens that can be matched against.

    If you wanted to match against the labels inside the suggestions arrays, you would need to change your datumTokenizer function to return Bloodhound.tokenizers.whitespace(suggestions.label).

    Or if you wanted to check against several properties, you would need to return an array of tokenizers like [Bloodhound.tokenizers.whitespace(suggestions.label), Bloodhound.tokenizers.whitespace(suggestions.language)].

    See snippet below of examples of matching against one and two properties of an array.

    $(document).ready(function() {
    
    const data = {"suggestions":[{"label":"United States Of America, NY, Cornwall, Angola Rd","language":"en","countryCode":"USA","locationId":"NT_7Cpok364jILgH4ksUcyjpC","address":{"country":"United States Of America","state":"NY","county":"Orange","city":"Cornwall","street":"Angola Rd","postalCode":"12518"},"distance":14896,"matchLevel":"street"},{"label":"United States Of America, NY, Garrison, Albany Post Rd","language":"en","countryCode":"USA","locationId":"NT_DM6n2RQmjZ1YvBjMS6MyGA","address":{"country":"United States Of America","state":"NY","county":"Putnam","city":"Garrison","district":"Garrison","street":"Albany Post Rd","postalCode":"10524"},"distance":23981,"matchLevel":"street"},{"label":"United States Of America, NY, Montrose, Albany Post Rd","language":"en","countryCode":"USA","locationId":"NT_NNt..Hu2Z5yXhvu4UpGXwA","address":{"country":"United States Of America","state":"NY","county":"Westchester","city":"Montrose","street":"Albany Post Rd","postalCode":"10548"},"distance":24394,"matchLevel":"street"},{"label":"United States Of America, NY, Croton-on-Hudson, Albany Post Rd","language":"en","countryCode":"USA","locationId":"NT_fokNpGY5GJxSkp195bkloA","address":{"country":"United States Of America","state":"NY","county":"Westchester","city":"Croton-on-Hudson","street":"Albany Post Rd","postalCode":"10520"},"distance":26329,"matchLevel":"street"}]};
    
    var suggestions = new Bloodhound({
        local: data.suggestions,
        datumTokenizer: function(suggestions) {
            return Bloodhound.tokenizers.whitespace(suggestions.label);
        },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
    });
    
    var suggestions2 = new Bloodhound({
        local: data.suggestions,
        datumTokenizer: function(s) {
            return ['countryCode','matchLevel'].reduce(function(p,c) {
            return p.concat(Bloodhound.tokenizers.whitespace(s[c]))
            }, []);
        },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
    });
    
    
    $('#order_address').typeahead({
            hint: true,
            highlight: true,
            minLength: 1
        },
        {
            name: 'suggestions',
            displayKey: function(suggestions) {
                return suggestions.label;
            },
            source: suggestions.ttAdapter()
    });
    
    
    $('#order_address2').typeahead({
            hint: true,
            highlight: true,
            minLength: 1
        },
        {
            name: 'suggestions2',
            displayKey: function(suggestions) {
                return suggestions.label;
            },
            source: suggestions2.ttAdapter()
    });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>
    <p>Matches against label only</p>
    <input type="search" class="typeahead" id="order_address" autocomplete="off">
    
    <p>Matches against countryCode and matchLevel</p>
    <input type="search" class="typeahead" id="order_address2" autocomplete="off">