Search code examples
angularjsjson-web-token

Angular 'Error: $injector:cdep Circular Dependency' when using factory in app.js


I am trying to use tokens to handle my user authentication. I hit a bump in the road and I am not entirely sure where to go from here. I looked around a bit, and it looks like I should use the $injector service, but I am not 100% sure. Could anyone please assist?

I created a factory that gets the token from node:

angular.module('myApp').factory('authenticateInterceptor', function(authenticateToken){

var authenticateInterceptorFactory = {};

authenticateInterceptorFactory.request = function(config){

    var token = authenticateToken.getToken();

    if(token){
        config.headers['x-access-token'] = token;
    };

    return config;
}

return authenticateInterceptorFactory;

});

Here is the code for autenticateToken:

angular.module('myApp').factory('authenticateToken', function($http, $window){

    authenticateTokenFactory = {};

    authenticateTokenFactory.getToken = function(token){
        return $window.localStorage.getItem('token');
    };

    return authenticateTokenFactory;

});

There are no errors here, the problem comes in when I try to use this factory in my app.js.

angular.module('myApp', [
    'dependancies goes here'
])
.config(function($httpProvider){
    $httpProvider.interceptors.push('authenticateInterceptor');
});

This now causes the error, I can't seem to pass my factory into the interceptors.


Solution

  • Most likely the circular dependency is caused by the injection of $http service inside authenticateToken factory

    the conflict exists because at bootstrap phase angular try to resolve $http dependencies (as well as other core services) in this order.

    1. $httpProvider dependencies
    2. authenticateInterceptor dependencies
    3. authenticateToken dependencies (include $http, and here we go back to 1.)

    By the way, since the $http service is not used in authenticationFactory you can even remove the injection, but if you need the service you can try injecting it dynamically only by need to avoid this behaviour.

    angular.module('myApp').factory('authenticateToken', function($injector, $window){
    
        authenticateTokenFactory = {};
    
        authenticateTokenFactory.getToken = function(token){
            return $window.localStorage.getItem('token');
        };
    
       authenticateTokenFactory.otherMethod = function(){
        //this code is not reached when your interceptor is added to 
        //$httpProvider interceptors array so theorically neither the exception
         var http = $injector.get('$http');
         http.get (/)...
    
       }
    
        return authenticateTokenFactory;
    
    });