Skip to content Skip to sidebar Skip to footer

Callback In Jquery Ajax Not Working When Using Jquery Ajax Cache Code Below

Below is my code and issue is with cache code is not working properly if any ajax call has callback in success. var localCache = { /** * timeout for cache in millis *

Solution 1:

As discussed in the chatroom I've made some changes in your code :

var localCache = {
  /**
   * timeout for cache in millis
   * @type {number}
   */timeout: 30000,
  /** 
   * @type {{_: number, data: {}}}
   **/data: {},
  remove: function(url) {
    delete localCache.data[url];
  },
  exist: function(url) {
    return !!localCache.data[url] && ((newDate().getTime() - localCache.data[url]._) < localCache.timeout);
  },
  get: function(url) {
    console.log('Getting in cache for url ' + url);
    return localCache.data[url].data;
  },
  set: function(url, cachedData, callback) {
    localCache.remove(url);
    localCache.data[url] = {
      _: newDate().getTime(),
      data: cachedData
    };
    console.debug('caching data for '+url, cachedData);
    if ($.isFunction(callback)) callback(cachedData);
  }
};

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
  if (options.cache) {
    var complete = originalOptions.complete || $.noop,
      url = originalOptions.url;
    //remove jQuery cache as we have our own localCache
    options.cache = false;
    options.beforeSend = function() {
      if (localCache.exist(url)) {
        console.log('using cache, NO QUERY');
        complete(localCache.get(url));
        returnfalse;
      }
      console.log('sending query');
      returntrue;
    };
    options.complete = function(data, textStatus) {
      localCache.set(url, data, complete);
    };
  }
});

functionhandleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
  method = method || "GET";
  headers = headers || {};
  parameters = parameters || {};

  return $.ajax({
    method: method.toUpperCase(),
    url: url,
    cache: true,
    //            async: false,data: parameters,
    headers: headers,
    success: successHandler,
    error: errorHandler,
  });
}

handleAjaxRequests('/echo/json/', {p1: 'hey'}, null, 'POST', function(data){console.log('first success without cache', data);});

setTimeout(function(){
handleAjaxRequests('/echo/json/', {p1: 'hey'}, null, 'POST', function(data){console.log('success! with cache hopefully', data);});
}, 2000);

Fiddle here

  1. added some logs in the localCache methods to see what's happening. Cache is never used so I've added the missing cache:true option
  2. Added some logs inside beforeSend method to monitor the toggle between cache and query. Everything works fine.
  3. Cleaned up the arguments null checks and removed empty function(){} (use $.noop() instead btw.
  4. Now the core of your issue. The callbacks errorHandler and successHandler are arguments. $.ajax is asynchronous! it means at some point of the execution, right after this call is made, you won't be sure if the variable has the same value. Easiest solution is to just reference the function directly and let jQuery do the scope management. Hardest solution would be to give these functions to the context option in ajax settings which I don't recommend.

Now, the solution you use allows you to directly call $.ajax without a wrapper method. Why don't you use it directly? simpler and less prone to errors


EDIT: I'm really not fond of context so there is another alternative.

functionhandleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
  method = method || "GET";
  headers = headers || {};
  parameters = parameters || {};

  return $.ajax({
    method: method.toUpperCase(),
    url: url,
    cache: true,
    //            async: false,data: parameters,
    headers: headers,
    success: (function(handler, opt) {
      returnfunction(/*Anything*/ data, /*String*/ textStatus, /*jqXHR*/ jqXHR) {
        console.log('hi');
        handler(data, opt);
        console.log('bye');
      };
    })(successHandler, options),
    error: (function(handler, opt) {
      returnfunction(/*jqXHR*/ jqXHR, /*String*/ textStatus, /*String*/ errorThrown) {
        console.log('ouch');
        handler(errorThrown);
      };
    })(errorHandler, options),
  });
}

You scope the function with this well known javascript trick aka currying.

New fiddle here.


EDIT 2: if you want successHandler to run even when getting from cache you should use complete instead of success

functionhandleAjaxRequests(url, parameters, headers, method, successHandler, options, errorHandler) {
  method = method || "GET";
  headers = headers || {};
  parameters = parameters || {};

  return $.ajax({
    method: method.toUpperCase(),
    url: url,
    cache: true,
    //            async: false,data: parameters,
    headers: headers,
    complete: (function(handler, opt) {
      returnfunction(/*Anything*/ data, /*String*/ textStatus, /*jqXHR*/ jqXHR) {
        console.log('hi');
        handler(data, opt);
        console.log('bye');
      };
    })(successHandler, options),
    error: (function(handler, opt) {
      returnfunction(/*jqXHR*/ jqXHR, /*String*/ textStatus, /*String*/ errorThrown) {
        console.log('ouch');
        handler(errorThrown);
      };
    })(errorHandler, options),
  });
}

Fiddle here.

Post a Comment for "Callback In Jquery Ajax Not Working When Using Jquery Ajax Cache Code Below"