Angular $http caching: How to identify a cached response vs actual $http.get

894 Views Asked by At

I'm using Angular $http.get() in an Ionic app to make API calls to an external service, and have implemented the CacheFactory plugin to make the caching more configurable.

Everything is working fine, if I make repeat API requests to the same endpoints, CacheFactory returns the cached response and I don't see an actual HTTP requests in my browser console, until the cache expires time has passed.

But I'd like to be able to identify whether the data I'm using has come from the cache or from a new HTTP request. How can I do this?

Having console logged the output of $http.get() I don't see anything useful, in fact the response object from either the cache or the HTTP call is identical.

Any ideas gratefully received.

1

There are 1 best solutions below

0
Raulucco On

You can use memorize the inputs of your request so when you invokes the get method you if the memorizer objects contains a key equal to the hash form by the request params then you know this request is going to be cached as long as it contains the same params as other request before. Under each key you can save a timestamp to calculate the difference between the milliseconds since the first time that request was done and now.

// some where on your code

app.factory('MyMemorizer', ['EXPIRATION_CACHE_TIME', function 

(EXPIRATION_CACHE_TIME) {
// EXPIRATION_CACHE_TIME constant with the milliseconds of the expiration cached
var memo = {};
  return {
    entryExist: function (obj) {
      var timestamp = getEntry(inputs),
      timeDelta = Date.now() - timestamp;
      return timeDelta > EXPIRATION_CACHE_TIME);
    } 

  };

  function getEntry(obj) {
      var hash = createHash(obj);
      if (memo.hasOwnProperty) {
        return memo[hash];
      }

      memo[hash] = Date.now();
      return memo[hash];
    }


  function createHash(obj) {
   var arr = [];
   for (prop in obj) {
     if (obj.hasOwnProperty(prop)) {
       arr.push(encodeURIComponent(prop) + '=' + encodeURIComponent(obj[prop]));
     }
   }

   return arr.join('&');
  }

});

Then inject it on a controller or a service or where you need it.

function invokeGetRequest (inputs) {

  // ... do your request

  if (MyMemorizer.entryExist(inputs)) {
    // request is cached
  }

}