Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS redirect not occurring in interceptor

I'm using a very simple interceptor to check responseRejection for 403 Access Forbidden to redirect users to the login, but it doesn't redirect. I can console.log right up to the line before $location.path and after it, and it never occurs. Has anyone else had this happen? I've been staring at this for a bit now... Originally I didn't even want to use $location, but I can't inject ui.router without getting a circular dependency, which I also can't figure out how to get rid of so $location was supposed to keep me moving, while I thought about it.

.factory('AuthInterceptor', ['$q', '$location',
    function( $q, $location ) {

    var service = {
        responseError: function( responseRejection ) {

            // Authorization issue, access forbidden
            if( responseRejection.status === 403 ) {

                // TODO: show a login dialog, and/or redirect to login
                console.log("Response rejected. Redirecting to login...");

                $location.path('/login');
                $location.replace();

                console.log("Not so much with the redirecting... I'm still here");
            }

            // Propagate error to any chained promise handlers
            return $q.reject( responseRejection );
        }
    }

    return service;
}])
like image 554
mtpultz Avatar asked Oct 31 '22 15:10

mtpultz


1 Answers

When setting the window location using location.href it does set the location immediately and stop the execution of scripts, but the location change will be effective only when the current script path under execution is completed. That is why you see statement below href gets executed. It is not a blocking activity as well (unlike alert or prompt). When setting location using the angular wrapper it will take effect after the digest cycle. And you have a valid issue of circular dependency when injecting $state in $http interceptor. To overcome that you can get the instance of $state by using $injector.

.factory('AuthInterceptor', ['$q', '$injector',
    function( $q, $injector ) {

    var $state;

    var service = {
        responseError: function( responseRejection ) {

            // Authorization issue, access forbidden
            if( responseRejection.status === 403 ) {

                // TODO: show a login dialog, and/or redirect to login
                console.log("Response rejected. Redirecting to login...");

                _setState('login');

                console.log("Not so much with the redirecting... I'm still here");
            }

            // Propagate error to any chained promise handlers
            return $q.reject( responseRejection );
        }
    }
   function _setState(stateName){
        if(!$state) {
          $injector.get('$state'); //Or just get $state from $injector always it is anyways the dependency container and service are singletons
        }
       $state.go(stateName);
    }
    return service;
}]);
like image 117
PSL Avatar answered Nov 11 '22 03:11

PSL