Injecting $state (ui-router) into $http Interceptor is causing circular dependency error, how to resolve?

Asked

Viewed 133 times

2

What I need:

I need when http request returns error 401 or 403 the user is redirected to login screen.

Problem:
The problem happens when I inject $state into my Factory, causes circular dependency error:

Uncaught Error: [$injector:cdep] Circular dependency found: $http <- $templateFactory <- $view <- $state <- Interceptorrequestfactory <- $http <- $translatePartialLoader http://errors.angularjs.org/1.5.9/$injector/cdep? P0=%24http%20%3C-%20%24tem... erceptorRequestFactory%20%3C-%20%24http%20%3C-%20%24translatePartialLoader

Code:

(function () {
  'use strict';

  angular
    .module('app.factory')
    .factory('InterceptorRequestFactory', InterceptorRequestFactory);

  function InterceptorRequestFactory($q, $state) {
    return{
      request: function(config){
        return config;
      },
      requestError: function(rejection){
        console.log(rejection);
        return $q.reject(rejection);
      },
      response: function(response){
        return response
      },
      responseError: function(rejection){
        console.log(rejection);
        if(rejection.status === 401 || rejection.status === 403){
          $state.go('app.login');              
        }
        else{
        return $q.reject(rejection);
        }
      }
    };
  }

})();

1 answer

2


To fix the problem just inject the $state manually using the service $injector, below an example seen in an answer from Soen:

var interceptor = ['$location', '$q', '$injector', function($location, $q, $injector) {
    function success(response) {
        return response;
    }

    function error(response) {

        if(response.status === 401 || response.status === 403) {
            $injector.get('$state').transitionTo('public.login');
            return $q.reject(response);
        }
        else {
            return $q.reject(response);
        }
    }

    return function(promise) {
        return promise.then(success, error);
    }
}];

$httpProvider.responseInterceptors.push(interceptor);

The problem is because the angular-ui-route injects the service $http as dependence within the $templateFactory, and this creates a circular reference to $http with $httpProvider. That’s why we should do the injection manually.

This problem will also occur if you try to inject the $http service, as exemplified in Jonathan Palumbo’s reply:

var interceptor = ['$location', '$q', '$http', function($location, $q, $http) 

Browser other questions tagged

You are not signed in. Login or sign up in order to post.