Search code examples
javascriptangularjsdependency-injectioncircular-dependencyservice-locator

Injecting $http service into $http interceptor?


I have the following interceptor:

var interceptor = ['$http', '$q', function ($http, $q) {
     //...
}];

This generates a circular dependency, because $http will depend on this interceptor, and this interceptor will depend on $http.

I want to get the $http service because I intend to refresh some authorization tokens of the user if I get a 401 Unauthorized response.

For this, I have to call my OAuth endpoint and retrieve the new tokens.

How can I inject this service into my interceptor?

I also tried the following alternative:

var interceptor = ['$injector', '$q', function ($injector, $q) {
     var $http = $injector.get('$http');
}]

But I'm getting the same error.

Is this possible?

I don't want to use the jQuery library and I want my application to be pure AngularJS, so $.ajax(...) answers are not useful to me.


Solution

  • Even the second snippet causes cdep error because interceptor service will get instantiated and in the constructor you are trying to get $http in the process, which causes cdep error. You would need to get the http service (or any of your service that injects http) later, after interceptor service has been instantiated. You could easily get it from $injector on demand when you need it, example on a reponseError.

    var interceptor = ['$injector', '$q',
        function($injector, $q) {
          return {
    
            responseError: function(rejection) {
              //Get it on demand or cache it to another variable once you get it. But you dont really need to do that you could get from the injector itself since it is not expensive as service is a singleton.
              var $http = $injector.get('$http');
              //Do something with $http
              return $q.reject(rejection);
            }
          }
        }
      ]