Angular – Caching $http calls using $cacheFactory service

In this post I am going to explain how we can cache requests to REST backends in our angular applications.

Introduction to $cacheFactory
Angular $cacheFactory is a service that allows us to create and access Cache objects. Think on a Cache as a simple key value store with put, get, destroy methods.

var myCache = $cacheFactory('cacheId');
myCache.put('key', 'value');
console.log(myCache.get('key'));

The angular $http services could use that Cache objects to cache response data.

angular.module('app', [])
    .factory('MyService', function ($http, $cacheFactory) {
		var myCache = $cacheFactory('cacheId');
        return {
            getPerson: function (id) {
                $http
                    .get('//server.com/api/people/' + id + '/', {cache: myCache})
                    .then(function (result) {
                        console.log(result.data.name);
                    });
            }
        }
    });

It uses the request URL as a key to store values. In the previous example if we call getPerson for the same person twice it will perform a http request only the first time and will return directly from the cache the second time.

Caching in Swagger APIs
In my current apps I don’t use directly the $http service to interact with the backend APIs, instead I use swagger generated API services that abstract me from writing that code. But the generated services allows also to use cache functionality. The way that we should use it is passing a cache object as a parameter of the services methods.
For example, we have the API service CurrentUserApi and its method getCurrentUser.

var currentUserApi = new CurrentUserApi(RestDomains.myService);
currentUserApi.getCurrentUser();

And we want to use cache here to avoid hitting the backend multiple times. The only thing that we need to do is to pass a Cache object as a param of the getCurrentUser method and the API service will use it to cache requests. Again, notice that we don’t need to deal with the complexity of managing the cache ourselves.

var currentUserApi = new CurrentUserApi(RestDomains.myService);
var currentUserCache = $cacheFactory('currentUser');
currentUserApi.getCurrentUser({$cache: currentUserCache});

Using a CacheService
We can simplify the use of the cache in our services using the same cache object. For that we can create a singleton CacheService with a local cache created with $cacheFactory. It can be injected in our services and passed directly as the cache param.

angular
    .module('App')
    .factory('CacheService', ['$cacheFactory', function ($cacheFactory) {
        return $cacheFactory('CacheService');
    }]);
 
 
angular
    .module('App')
    .factory('UsersService', ['RestDomains', 'CacheService', 'CurrentUserApi', function (RestDomains, CacheService, CurrentUserApi) {
    var currentUserApi = new CurrentUserApi(RestDomains.myService);

    return {
        getCurrentUser: function () {
            return currentUserApi.getCurrentUser({$cache: CacheService});
        }
    };
}]);

Considerations
The use of caching in the angular services could reduce the number of requests that the single page application performs, improving performance and making the UI more responsive. But it is really important to choose properly the endpoints and resource to cache. Usually we want to cache resources that we now that are not going to change during the user “session”, resources like current user information, reference data, etc.

It is possible to use different implementations of the $cacheFactory services like angular-cache that provides Cache objects with timeouts or the possibility of caching using HTML5 local storage. The good thing of the angular’s built-in version is its simplicity.

Notice also that the use of Cache objects directly by the $http or the swagger APIs services it is a cleaner option that dealing directly in our service with the cache of values.

Documentation:
https://docs.angularjs.org/api/ng/service/$cacheFactory
https://egghead.io/lessons/angularjs-cachefactory
http://jmdobry.github.io/angular-cache/
https://github.com/wcandillon/swagger-js-codegen

Advertisements

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