Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: How can I cache json data returned from $http call?

How can I cache json data returned from $http call. I use the following style of $http call:

$http({
        url: 'SomeWebMethodUrl',
        method: "POST",
        data: "{'query':'somevalue'}",
        headers: { 'Content-Type': 'application/json' }
    }).success(function (data, status, headers, config) {
        //something in success
    }).error(function (data, status, headers, config) {
        //something in error
    });

I looked at the following tutorial: https://coderwall.com/p/40axlq on caching server response from $http call. But it is explaining $http.get() style and will cache data and will not make second $http request if the absolute URL is same.

Can I use caching with my style of $http call when my 'data' property is same for same webmethod calls in future? I am using ASP.net ASMX webservice for my WebMethods.

like image 347
Pawan Pillai Avatar asked Feb 01 '14 17:02

Pawan Pillai


Video Answer


1 Answers

The angular.js cache is designed for HTTP GET calls only. This is consistent with the intent of the HTTP protocol, as HTTP servers don't usually look beyond the URL, the HTTP Method, and Cache-Control headers to determine whether they can respond to a request with cached content. Accordingly, the authors of angular did not extend the caching functionality to other HTTP methods.

Another way to look at it is that the angular $cache service is really just a simple key value store, with the URL of the request acting as a key and the response to the HTTP GET request the value that is stored locally instead of on the server.

When you think of it that way it becomes clear why it's more difficult to cache the response to a POST request. The content returned by the POST request depends not only on the URL, but the POSTed content. To cache that result in a key value store you need a mechanism to create an unique key that identifies both the URL and the data being passed.

If you data is simple enough, my suggestion is to write your own cache that is checked before you use the angular $http service. Without knowing more about your data method I can't give you a complete example, but you could do something like this:

angular.module('myModule').service('myDataService', function($cacheFactory, $http) {

  var cache = $cacheFactory('dataCache');

  function success(data, status, headers, config) {
    // some success thing
  }

  function error(data, stats, headers, config) {
    // some error thing
  }

  this.getSomeData = function(url, query) {
    var cacheId = url + '*' + query;
    var cachedData = cache.get(cacheId);
    // Return the data if we already have it
    if (cachedData) {
      success(cachedData);
      return;
    }

    // Got get it since it's not in the cache
    $http({url: url,
           method: 'POST',
           data: {query: query},
           headers: { 'Content-Type': 'application/json' }  // Probably not necessary, $http I think does this 
         }).success(function(data, status, headers, config) {
              // Put this in our cache using our 'unique' id for future use
              cache.put(cacheId, data);
              success(data, status, headers, configs);
         }).error(error);    

  };

});

You would then substitute this wrapper service where you currently use the raw $http service.

The point is to implement your own cache that understands the 'url+data' as a key before actually calling the $http service.

like image 185
Geoff Genz Avatar answered Oct 14 '22 13:10

Geoff Genz