Loading indicator with interceptors in AngularJS

The $http service of AngularJS allows us to communicate with a backend and make HTTP requests.
We want to handle a loading indicator for every request in a generic and a non-intrusive way.
AngularJS interceptors are created exactly for such cases.

What is an interceptor ?

An interceptor is a regular service factory.

There are two kinds of interceptors (and two kinds of rejection interceptors):

  • request: this interceptor is called before $http sends the request to the backend.
  • requestError: this interceptor gets called when a previous interceptor threw an error or resolved with a rejection.
  • response: this interceptor is called right after $http receives the response from the backend.
  • responseError: this interceptor gets called when a previous interceptor threw an error or resolved with a rejection.

request and response interceptors have to return either an object (config for request and response for response) or a promise.

Using interceptors

As stated before, an interceptor is a service factory:

module.factory('myInterceptor', ['$q', '$indicator', function($indicator) {  
    var pendingRequests = 0;
    return {
        request: function(config) {
        pendingRequests++;
        $indicator.show();
        return config || $q.when(config);
    },
    response: function(response) {
        if ((--pendingRequests) === 0) $indicator.hide();
        return response || $q.when(response);
    },
    responseError: function(response) {
        if ((--pendingRequests) === 0) indicator.hide();
        return $q.reject(response);
    }
};

This article is focused about interceptors, $indicator is considered as a black box that handles the display of an indicator like a spinner.

Interceptors are registered with the $httpProvider by adding them to the $httpProvider.interceptors array.
Last thing to do is to add the interceptor to the $httpProvider:

module.config(['$httpProvider', function($httpProvider) {  
    $httpProvider.interceptors.push('myInterceptor');
}]);

Through this article, I provide a pragmatic use of interceptors with a few useful details about them but they can be used in many other cases.