Understanding HTTP Interceptors In AngularJS

In this article we will learn about the HTTP Interceptors in AngularJS.

In a request and response communication of a HTTP call if we want to inject some custom logic the HTTP Interceptor comes into picture. HTTP Interceptors executes some custom logic before or after the HTTP call.

For example, appending the authentication token to every HTTP request and that token is generated from the client who needs to be validated at the server for security purpose.


These interceptors act as a hook up for the HTTP calls.

HTTP Interceptors are used for adding custom logic for authentication, authorization, session/state management, logging, modifying Response, URL rewriting, Error handling, Caching, adding custom header, timestamp in the request /response, encrypt and decrypt the request and response information or manipulate the request and response data over the request cycles.

 

HTTP Interceptors are similar to custom HTTP Module of ASP.NET.

There are four kinds of interceptors in AngularJS - Request, requestError, response, responseError

Syntax for creating Http Interceptors

  1. var Interceptor = function ($q)  
  2. {  
  3.     return {  
  4.         request: function (config)  
  5.         {  
  6.             return config;  
  7.         },  
  8.         requestError: function (rejection)  
  9.         {  
  10.             return $q.reject(rejection);  
  11.         },  
  12.         response: function (result)  
  13.         {  
  14.             return result;  
  15.         },  
  16.         responseError: function (response)  
  17.         {  
  18.             return $q.reject(response);  
  19.         }  
  20.     }  
  21. }  
  22. interceptorApp = angular.module('interceptorApp', []).config(function ($httpProvider)  
  23. {  
  24.     $httpProvider.interceptors.push(testInterceptor);  
  25. }); 

Let us see what these interceptors are and how they are used.

Request

This interceptor is called before $http sends the request to the server. This function takes the request configuration object as input parameter and returns a configuration object.

When there is need of adding, modifying or removing data prior to sending to the server for each request the request functions of the interceptors are used.

For example,

Let us consider we want to insert the authentication token to each request.

  1. request: function (config) {    
  2.     console.log('request started...');    
  3.     //Validating the requests and assign the csrf token to each requests     
  4.     var token = $cookieStore.get("auth");    
  5.     config.headers['x-csrf-token'] = token;    
  6.     return config;    
  7. }  

requestError

This interceptor gets called when a request interceptor threw an error or resolved with a rejection code.

For example,

Let us say some error has happened when request interceptors fail and it has blocked the HTTP call, and then log the rejection.

  1. requestError: function (rejection) {    
  2.     console.log(rejection);    
  3.     // Contains the data about the error on the request and return the promise rejection.    
  4.     return $q.reject(rejection);    

Response

This interceptor is called when the $http receives the response from the server.

This function receives a response object as a parameter return a response object or a promise. A response interceptor is used to modify the response data or adding a new set of values, calling another module or services call.

For example,

Let us consider the response which we have got from the service we need to manipulate and add some keys to the result.

  1. response: function (result) {    
  2.       console.log('data for ' + result.data.name + ' received');    
  3.   
  4.      //If some manipulation of result is required.                                result["testKey"] = 'testValue';    
  5.      console.log('request completed');    
  6.      return result;    
  7.  },  

Here result["testKey"] = 'testValue' is added to the result object to the UI Page.

responseError

There are some situations where one call has failed and the application need to trigger some action based on different HTTP status code. This interceptor receives a response object as a parameter return a response object or a promise. The application level generic error handling is achieved by using this interceptor.

For example,

Let us consider the situation of calling the HTTP service call has failed we need to show some error page or login page checking HTTP status code returned from the server.

  1. responseError: function (response) {    
  2.      console.log('response error started...');    
  3.   
  4.      //Check different response status and do the necessary actions 400, 401, 403,401, or 500 eror     
  5.      if (response.status === 401) {    
  6.          $location.path('/signin')    
  7.          $rootScope.$broadcast('error')    
  8.      }    
  9.   
  10.      if (response.status === 500) {    
  11.          $rootScope.ErrorMsg = "An Unexpected error occured";    
  12.          $location.path('/Error')    
  13.      }    
  14.      return $q.reject(response);    
  15.  }   
Code Example of an Interceptor
  1. <!DOCTYPE html>  
  2. <html ng-app="interceptorApp">  
  3.   
  4. <head>  
  5.     <script src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>  
  6.     <script>  
  7. var testInterceptor = function ($q)  
  8. {  
  9.     return {  
  10.         request: function (config)  
  11.         {  
  12.             console.log('request started...');  
  13.         },  
  14.         requestError: function (rejection)  
  15.         {  
  16.             console.log(rejection);  
  17.             // Contains the data about the error on the request and return the promise rejection.    
  18.             return $q.reject(rejection);  
  19.         },  
  20.         response: function (result)  
  21.         {  
  22.             console.log('data for ' + result.data.name + ' received');  
  23.             //If some manipulation of result is required before assigning to scope.    
  24.             result["testKey"] = 'testValue';  
  25.             console.log('request completed');  
  26.             return result;  
  27.         },  
  28.         responseError: function (response)  
  29.         {  
  30.             console.log('response error started...');  
  31.             //Check different response status and do the necessary actions 400, 401, 403,401, or 500 eror     
  32.             return $q.reject(response);  
  33.         }  
  34.     }  
  35. }  
  36. interceptorApp = angular.module('interceptorApp', []).config(function ($httpProvider)  
  37. {  
  38.     $httpProvider.interceptors.push(testInterceptor);  
  39. });  
  40. interceptorApp.controller('interceptorCtrl', ["$scope""$http",  
  41.     function ($scope, $http)  
  42.     {  
  43.         $scope.getData = function ()  
  44.         {  
  45.             var data = $http.get('http://localhost:52332/testwebapi').  
  46.             success(function (data, status, headers, config)  
  47.             {  
  48.                 $scope.Name = data.name;  
  49.             });  
  50.         };  
  51.     }  
  52. ])  
  53.     </script>  
  54. </head>  
  55.   
  56. <body ng-controller="interceptorCtrl"> {{ Name }}  
  57.     <input type="button" value="Click To Test Interceptors" ng-click="getData()" /> </body>  
  58.   
  59. </html>
Output

 

We see here that the console log has 'request started...’ and 'response error started...’ from the interceptors .

This was the basic understanding of HTTP Interceptors in AngularJS. Thanks for reading.