javascriptlodashtypeahead.jstwitter-typeahead

How to debounce ajax requests in typeahead.js


I am using twitter typeahead library to implement searching functionality.

I found the approach of sending POST request through ajax in typeahead.

Problem is: It is firing requests for every word I type no matter how fast or slow and on backspaces too.

Here is my code snippet:

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 2,
}, {
    source: function (query, process) {
        return $.ajax({
                url: "Somedomain" + "post/api/skills",
                type: 'post',
                data: { query: query, limit: 15 },
                dataType: 'json',
                success: function (result) {
                    console.log(result);
                    var resultList = result.skills.map(function (item) {
                        var aItem = { value: item };
                        return aItem;
                    });

                    process(resultList);
                    return;
                }
            });
    },
    displayKey: 'value',
});

I tried:

Using lodash library's debounce in source like this, but it is not sending any ajax requests.

Code snippet:

function debounceIt(query, process) {
    return $.ajax({
                url: "Somedomain" + "post/api/skills",
                type: 'post',
                data: { query: query, limit: 15 },
                dataType: 'json',
                success: function (result) {
                    console.log(result);
                    var resultList = result.skills.map(function (item) {
                        var aItem = { value: item };
                        return aItem;
                    });

                    process(resultList);
                    return;
                }
            });
}

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1,
}, {
    source: function (query, process) {
        _.debounce(function () {
             debounceIt(query, process);
        }, 300);
    },
    displayKey: 'value',
});

Can anyone help how to solve this? I tried seeing similar posts on stack overflow but couldn't find any solution.


Solution

  • I managed to solve this problem by using Bloodhound.

    Result data is in format:

    {status: "success", skills: ["coding", "coding theory"]}
    

    Code Snippet:

    var skills = new Bloodhound({
        datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.value);  },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
            url: "Somedomain" + "post/api/skills",
            rateLimitBy: 'debounce',
            rateLimitWait: 500,
            prepare: function (query, settings) {
                settings.type = "POST";
                settings.data = {query: query, limit: 15};
                return settings;
            },
            transform: allSkills => $.map(allSkills.skills, movie => ({
                value: movie
            }))
        },    
    });