Chapter 3
As the initial example, let's assume that we want to retry failed requests. To do so we
can define an interceptor that inspects response status codes and retries a request, if
the HTTP Service Unavailable (503) status code is detected. The sketch of the code
could look like:
angular.module('httpInterceptors', [])
.config(function($httpProvider){
$httpProvider.responseInterceptors.push('retryInterceptor');
})
.factory('retryInterceptor', function ($injector, $q) {
return function(responsePromise) {
return responsePromise.then(null, function(errResponse) {
if (errResponse.status === 503) {
return $injector.get('$http')(errResponse.config);
} else {
return $q.reject(errResponse);
}
});
};
});
An interceptor is a function that accepts a promise of the original request as its
argument, and should return another promise resolving to an intercepted result.
Here we inspect the errResponse.status code to check if we are in the error
condition where we can try to recover. If so, then we are returning a promise from
a completely new $http call done with the same configuration object as the original
request. If we happen to intercept an error that we can't handle we are simply
propagating this error ($q.reject method).
AngularJS interceptors make have use of the promise API, and this is what makes
them so powerful. In the example described here we can retry an HTTP request in
a way that is completely transparent to clients using the $http service. Chapter 7,
Securing Your Application, has a complete example of using response interceptors to
provide sophisticated security mechanism.
Registering new interceptors is easy, and boils down to adding a reference to a new
interceptor (here an AngularJS service created via factory) to an interceptor array
maintained by the $httpProvider. Please note that we are using a provider to register
new interceptors, and the providers are only available in configuration blocks.