Skip to content

Using custom cache object with AngularJS $http

September 30, 2015

Hello

At work, I’ve been bitten by the way AngularJS handles cache by default when using $https service. This post will show a simple way to improve cache handling with $http service.

The service I’m working on must perform the followings tasks:

  • retrieve data from a remote server.
  • save data to the same server.
  • retrieve the saved data and some extra information generated by the server to update a UI

At first, I’ve naively used $http.get cache parameter to enable or disable caching using a sequence like:

  1. $http.get(url, {cache: true} )
  2. $http.post(url)
  3. $http.get(url, {cache: false})
  4. $http.get(url, {cache: true})

Let’s say the calls above use the following data:

  1. $http.get(url, {cache: true}) returns “foo”
  2. $http.post(url) stores “bar”
  3. $http.get(url, {cache: false}) returns “bar”

I expected the next call $http.get(url, {cache: false}) to return “bar”. But no, I got “foo”, i.e. the obsolete data.

Turns out that cache object is completely left alone when {cache: false} is passed to $http.get.

ok. Fair enough. But this means that the value of the cache parameter should not change for a given URL. The default cache provided by $https cannot be cleared. (Well, actually, you can clear the cache under AngularJS’s hood, but that will probably not improve the readability of your code).

The naive approach does not work. Let’s try another solution by using a custom cache object as suggested by AngularJS doc. This cache object should be created by $cacheFactory service.

This cache object can then be passed to $http.get to be used as cache. When needed, the cache can be cleared. In the example above, the cache must be cleared after saving some data to the remote service.

There’s 2 possibilities to clear a cache:

  • Completely flush the cache using removeAll() function.
  • Clear the cache for the specific URL using remove(key) function. The only hitch is that the “key” used by $http is not documented.

So, we have to use the first solution and create a cache object for each API entry point:

angular.module('app').factory('myService', function ($http, $cacheFactory) {
  var myFooUrl = '/foo-rest-service';
  
  // create cache object. The cache id must be unique
  var fooCache = $cacheFactory('myService.foo'); 
  function getFooData () {
    return $http.get( myFooUrl, { cache: fooCache });
  };
 
  function saveFooData(data) {
    return $http.post( myFooUrl, { cache: fooCache }).then(function() {
      myCache.removeAll() ;
    });
  }
});

The code above ensures that:

  • cached data for foo service is always consistent
  • http get requests are not sent more than necessary

This simple approach has the following limitations:

  • cache is not refreshed if the data on the server are updated by another client
  • cache is flushed when only the browser page is reloaded

If you need more a more advance cache mechanism, you may want to check jmdobry’s angular cache project

All the best

Advertisements

From → Uncategorized

2 Comments
  1. Hi Dominique (had to google you on debian to find your 1st name).
    I would like to thank you for you clear post on LWP, proxy, and https issues. I had been struggling with it for 3 days trying to understand what was going on. Thank you
    Also, I am a unix sysadmin that programs in perl and python using VI and I have been usually doing programming jobs in php and JS. I dont like JS but I need to deal with it. What do you use to program in JS? I am the kind of guy who open an xterm with VI and another one with bash where I execute my script, and thats how I develop. Is there a similar way to develop in JS? I tried using VI and NODE.JS but JS in NODE is kinda different from within the browser.
    Thanks for any advice, and congrats for being part of the debian team!!
    p.s. plz delete the 1st post, I forgot to check the notification box

  2. Hello Andre

    Thanks for the nice words. I’m kinda old school and use emacs with js2-mode, js2-refactor and helm to edit JavaScript files. Currently I mostly work on AngularJS 1.2 and sometimes on node. I use emacs for both.

    All the best

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: