user3705773
user3705773

Reputation: 97

How to prevent duplicated AJAX call?

I'm currently building a simple AJAX call application which will show the result of a textbox after typing some texts inside it:

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

$(document).ready(function(e) {

    $("input[name=html]").keyup(function(e) {
        if(this.value.length > 1) {        
            e.preventDefault();
            var form = $(this).closest('form');
            var form_data = form.serialize();
            var form_url = form.attr("action");
            var form_method = form.attr("method").toUpperCase();
            delay(function(){
                $("#loadingimg").show();
                $.ajax({
                    url: form_url, 
                    type: form_method,      
                    data: form_data,     
                    cache: false,
                    success: function(returnhtml){                          
                        $("#result").html(returnhtml); 
                        $("#loadingimg").hide();                    
                    }           
                });    
            },1000);
        }
    });

});

Fiddle Demo

As you can see from the demo above, for instance if you type test,test1 or test2 or any word as long as their length is longer than one then it'll make an AJAX call.

My question is that is there any way that allow me to prevent duplicate AJAX call? For example if I type test in the textbox again, it'll immediately show test in the div without making another AJAX call to fetch the result again. Thank you very much in advance.

Upvotes: 0

Views: 1974

Answers (1)

jfriend00
jfriend00

Reputation: 707328

You just need to cache previous results and, before making the ajax call, check the cache to see if you already have that result in the cache.

In Javascript, one usually uses an object for a cache:

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

// create cache for ajax results
// the key is the form_data
// the value is whatever the ajax call returns
var ajaxCache = {};

$(document).ready(function(e) {

    $("input[name=html]").keyup(function(e) {
        if(this.value.length > 1) {        
            e.preventDefault();
            var form = $(this).closest('form');
            var form_data = form.serialize();
            // check the cache for a previously cached result
            if (ajaxCache[form_data]) {
                 // this uses delay, only so that it clears any previous timer
                 delay(function() {
                     $("#result").html(ajaxCache[form_data]); 
                     $("#loadingimg").hide();
                 }, 1);
            } else {
                var form_url = form.attr("action");
                var form_method = form.attr("method").toUpperCase();
                delay(function(){
                    $("#loadingimg").show();
                    $.ajax({
                        url: form_url, 
                        type: form_method,      
                        data: form_data,     
                        cache: false,
                        success: function(returnhtml){                          
                            $("#result").html(returnhtml); 
                            // put this result in the cache
                            ajaxCache[form_data] = returnhtml;
                            $("#loadingimg").hide();                    
                        }           
                    });    
                },1000);
            }
        }
    });
});

Working demo: http://jsfiddle.net/jfriend00/P2WRk/

Upvotes: 4

Related Questions