CJ Broersma
CJ Broersma

Reputation: 189

jQuery html function acting asynchronous instead of synchronous

I am a bit bewildered. I have a function that calls an ajax search on keyup below.

$(document).on('keyup', '#search', function(e) {
        $("#showPending").html("");
        if ($('#showPending').is(':empty')){
            if ( this.value.length > 2  ) {

                var search = $("#search").val();
                loadsearch(search);
            }
        }
    });

Everything works great except if the user types a search parameter quickly he/she will get duplicate records appended to the #showPending table. If they type slowly they will get perfect results. I was under the impression the loadsearch function will not be called until after the #showpending element is empty because it is a synchronous function. Any ideas what I am doing wrong? Cheers! update: load search function (minimized) below:

function loadsearch(search){

    $("#showPending").html("");
    
    $.ajax({
    url: "server-calls/load-search.php?callback=?",
    type: "GET",
    data: {search: search},
    dataType: "jsonp",
    crossDomain: true,
    success: function (data, status) {
            for(var i = 0; i < data.length; i++) {
            var obj = data[i];
                
            $("#showPending").append('<a href="javascript:void(0);">SEARCH RESULTS </a>');
            }
        
        }                                   
    });     
}

Upvotes: 2

Views: 128

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370699

You can abort the previous XHR at the beginning of calling loadsearch, so that the prior request doesn't go to its success handler:

let request;
function loadsearch(search){
    request?.abort();
    $("#showPending").html("");
    
    request = $.ajax({
        // ...

You can also send out a request only after a certain amount of time has passed since the last input, maybe 500ms:

let timeout;
$(document).on('keyup', '#search', function (e) {
    $("#showPending").html("");
    if ($('#showPending').is(':empty')) {
        if (this.value.length > 2) {
            var search = $("#search").val();
            clearTimeout(timeout);
            timeout = setTimeout(() => loadsearch(search), 500);
        }
    }
});

For the best experience, I'd recommend using both approaches together.

Upvotes: 1

Related Questions