Circular http dependency found: $http <- Authservice <- Authinterceptor <- $http <- $templateRequest <- $route'

Asked

Viewed 242 times

1

I’m having the http circular dependency problem at the angle.

I have seen other questions with similar subject, but the ways I have tried I have not yet managed to solve the problem..

My Code:

var app = angular.module("app", [
    "ngRoute",
    "ngResource",
    "toastr",
    "ngStorage"    
    ]);

app.factory( "AuthService", AuthService );
app.factory( "AuthInterceptor", AuthInterceptor );


app.config(["$httpProvider", function( $httpProvider){

        $httpProvider.interceptors.push("AuthInterceptor");

}]);

app.run(function ($rootScope, $location, AuthService) {

    $rootScope.$on('$routeChangeStart', function (event, next, current) {

        if (!AuthService.getToken()) {

          $rootScope.$evalAsync(function () {
            $location.path('/signin');
          })
        }
    });

});

function AuthService($localStorage, $http, $q) {

  return {
    getToken : function () {
      return $localStorage.token;
    },
    setToken: function (token) {
      $localStorage.token = token;
    },
    login : function (data) {
      $http.post(URL+"user/login", data);
    },
    logout : function (data) {
      delete $localStorage.token;
      $q.when();
    }
  };
}



function AuthInterceptor($location, AuthService, $q ) {

  return {
    request: function(config) {
      config.headers = config.headers || {};

      if (AuthService.getToken()) {
        config.headers['Authorization'] = 'Bearer ' + AuthService.getToken();
      }

      return config;
    },

    responseError: function(response) {

      if (response.status === 401 || response.status === 403) {
        $location.path('/signin');
      }

      return $q.reject(response);
    }
  }
} 

When I execute this error is displayed,

[$injector:cdep] Circular dependency found: $http <- Authservice <- Authinterceptor <- $http <- $templateRequest <- $route

Authinterceptor needs Authservice to configure the request header, I think that internally it uses $http, this justifies the circular dependency error.. but I need the $http service in Authservice, to perform the Login and Logout requests...

Can someone help me?

2 answers

1

@Onosendai after refactoring with his advice of separation of responsibilities, worked perfectly. Create an Authorizeservice with getToken and setToken, and the Authenticservice that login, logout.. I can thus inject Provider $http into Authenticservice normally,

In the end it was like this, sharing, it may help other people,


var app = angular.module("app", [
    "ngRoute",
    "ngResource",
    "toastr",
    "ngStorage"    
    ]);

app.factory( "AuthenticService", AuthenticService );
app.factory( "AuthorizeService", AuthorizeService );
app.factory( "AuthInterceptor", AuthInterceptor );

app.config(["$httpProvider", function($httpProvider){

        $httpProvider.interceptors.push("AuthInterceptor");

}]);

app.run(function ($rootScope, $window, AuthorizeService) {
   $rootScope.$on('$routeChangeStart', function (event, next, current) {
        if (!AuthorizeService.getToken()  ) {

            event.preventDefault();

            $rootScope.$evalAsync(function () {            
                $window.location.href = "/login.php";            
            });
        };  

    });

});

function AuthenticService($localStorage, AuthorizeService, $http, $q) {

  return {
    login : function (data) {
      $http.post(URL+"auth/login", data)
      .then(function(data){

            var result = null;

            if (data && data.data instanceof Object) {

                result = data.data;

                if ( result["success"] ) {

                    $localStorage.token = result["token"]; 
                    $window.location.href = '/projeto/frontend/';
                    AuthorizeService.setToken(data.data);

                } else if ( result["error"] ) {

                    alert("Não foi possível autenticar, " + result["msg"] );

                } else {

                    alert("Ocorreu um erro no servidor" );
                }
            }   

      });
    },

    logout : function (data) {
      delete $localStorage.token;
      $q.when();
    }
  };
}


function AuthorizeService($localStorage, $window, $q) {

  return {

    getToken : function () {
      return $localStorage.token;
    },

    setToken: function (data) {         
        if (data instanceof Object) {
            if ( data["success"] ) {
                $localStorage.token = data["token"]; 
                $window.location.href = '/projeto/frontend/';

            } else if ( data["error"] ) {
                alert("Não foi possível autenticar, " + data["msg"] );
            } else {
                alert("Erro" );
            }
        }          
    }

  };
}

function AuthInterceptor($location, AuthorizeService, $q ) {

  return {

    request: function(config) {
      config.headers = config.headers || {};

      if (AuthorizeService.getToken()) {
        config.headers['Authorization'] = AuthorizeService.getToken();
      }

      return config;
    },

    responseError: function(response) {

      if (response.status === 401 || response.status === 403) {
        $location.path('/signin');
      }

      return $q.reject(response);
    }
  }
}


Thank you very much partner!

0

Authservice has a method, login(), which is not used in any part of the code. It is also the only section that uses the previous $http.

Solution: Remove, from AuthService, the injection of service $http and the function login().

  • Hi good afternoon, yeah. remove the login with $http is a solution, but then I would have to log in from another point, so I can’t concentrate this type of request ( login, logou ) in the same Factory.. but thanks for the answer, I think I’ll opt for that very thing..

  • @Fabiomoura are two different scopes, authorization and authentication. You can have an authentication service with the methods of Sign in and Sign out, and another authorization service that checks if the token is loaded and valid. Tie the authentication service to a route/status, and configure the Interceptor to ignore the required endpoints.

Browser other questions tagged

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