Understanding angular $http interceptors

Angular JS  built in service  $http  is used to make http server requests.  More often than not you would find yourself in a situation where you would want to run hooks for the http calls, i.e execute some logic before or after the http call. For example appending the auth token  to every api request or generic http response error handling. For this $http interceptors become quite handy. One more very important use of interceptors is to log http requests made to external API’s which can be used for analytics.

Although there is not a lot written about interceptors on the documentation site, reading through the code comments makes much more sense. One way to implement interceptors is to create a service and implement the required hooks as functions in the service and then push the service to interceptors array. Or  by pushing  an anonymous factory(function) with the required functions to http interceptors array. There are four types of interceptors Request, Response, Request error and Response Error. Every interceptor factory should have one out of these four methods defined rest are optional.

Let’s clear things with an example.

Response Interceptor

A response interceptor function takes a promise object as argument and returns the resolved promise.  The example Below handles 401 errors from the servers and does suitable error handling.  If the http request returns a success response it does not do anything. But if there is a error, it checks for the error code from the server and if its 401, redirects the user to the login page.

Request Interceptor

A request interceptor function takes in a config object and returns a modified config object.  In the Example Below we are going to add a ‘auth token’ parameter to every request made to the API server.

Although the examples above have implemented two different factories for simplicity, they can be combined into a single factory. And the interceptor looks like the one below.

Final Gist borrowed form https://gist.github.com/gnomeontherun/5678505

Advertisements

38 thoughts on “Understanding angular $http interceptors

    • Hey Michal All $http requests are async and hence use promise. So the example here is using a promise for the response interceptor. If you need anything more let me know.

  1. Well, I want to create an interceptor that will make an $http call and append the result of that call as a header to the first (intercepted) call. Could you show me an example of that?
    I understand the basics of promises, but they are not entirely clear to me in those complicated chaining situations.

  2. Not exacly. I’m working with SharePoint, and everytime I want to create or update some item, I need to first call other endpoint to get a token called form digest. Then, I have to attach that token to header of post request, as a validation – without it, any update operation won’t work.

    • Iam not sure if interceptor will solve your problems. I think you should understand promises in a better way. You can encapsulate the logic in a function. You can either post a question on Stack overflow or mail me if you need more help.

  3. Looks like your final example sould be updated…

    Could you update the interceptor name to match the one you defined (‘MyHttpInterceptor’)?

    Thanks for the great example!

  4. Hi,
    First of all thanks for such great self-explanatory tutorial for $http interceptors.
    I am looking to implement this into my project where user authentication is required. I have used your response interceptor code but getting following error:
    “TypeError: Object # has no method ‘then'”
    I debugged and found out that promise is not getting any valid value. It would be great if you can extend your help over this problem.
    Thanks in advance.

  5. angular.module(‘myApp’)
    .factory(‘UserAuthentication’,[‘$q’,’$location’,function($q,$location){
    return {
    response: function(promise){
    return promise.then(
    function success(response) {
    console.log(‘User authentication is done successfully!!!’)
    return response;
    },
    function error(response) {
    if(response.status === 401){
    console.log(‘User authentication is failed. The user is logged out!!!’)
    return $q.reject(response);
    }
    else{
    return $q.reject(response);
    }
    });
    }
    }
    }]);

  6. angular.module(‘myApp’, [‘ngRoute’,’ngCookies’,’ngSanitize’])
    .config(function ($routeProvider,$locationProvider,$httpProvider) {
    $httpProvider
    .interceptors.push(‘UserAuthentication’);
    });

  7. Hey, thanks for this, I do have a problem though. In the response interceptor I’m getting a “promise is not defined” error, which actually seems to make sense, as I can’t see where it would be. Could you help me out with this?

  8. What would be an example of a request error? Aren’t most errors response errors? I haven’t been able to figure out when that requestError would be called. I’ve forced a responseError in testing but what would cause a requestError? Thanks

    • Iam not really sure what would be a request Error, but it could be some missing header or something which is caught at the client before making a request to the server.

  9. Thanks for the great article.
    My question is that given the power of interceptors, does it make sense to wrap $http in a service so that all my other code just calls that wrapper. Though I cant think of a valid usecase now, but lets say just to shield any future api changes etc to $http? Or maybe later migrate to $resource?
    Also please note that here I am talking of a basic wrapper service around $http’s methods, not a client service like DataService with methods sendData, receiveData that wraps $http calls.
    Hope it makes sense!
    Thanks.

    • Its exactly how you should be dealing with server calls. The advantage being it decouples your data layer logic from the controllers. We do this in all our projects. A good practices would be return a promise instead of returning the fetched data, this makes the wrapper completely reusable. Also Bonus, please check Restangular.

      • Thanks. Can you please show a working sample, if possible.
        Also just to be clear, what $http wrapper service I was talking is like this –

        angular.module(‘myapp’).factory(‘myhttpwrapper’, [‘$http’, function (http) {
        return {

        myGet: function (getUrl) {
        return http.get(getUrl);
        });
        },
        myPost: function (postUrl, data) {
        return http.get(postUrl, data);
        });
        },
        // other $http wrappers
        };
        }]);

        Now all other code will use myhttpwrapper’s myGet, myPost methods instead of $http’s get, post methods. Does this makes sense?

        Thanks.

  10. Pingback: Better Authorization (Facepalm Redemption) | Darc Inc Writes Code

  11. Pingback: AngularJS-Learning | Nisar Khan

  12. Hey, nice article. I was actually trying to inject $http dependency in interceptor. I get a “circular dependency error”. Can you suggest any alternate way to achieve this?

  13. This is amazing and I’m able to see all the captured requests and responses. Now, I don’t want to put my retry code in the Factory especially if I need to implement different requirements. Where is the best place to put the retry code like redownloading of a resource that previously failed?

    Thanks a lot!

  14. Pingback: Angular HTTP interceptors | CSharper

  15. Pingback: How could you become zero to hero in AngularJS? | Milap Bhojak

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