6

I am pretty new to angular, and I had a question on the best way to handle a redirect within an interceptor.

I have certain pages in my app that I should only be able to access if I have an account selected. So if an account is not selected I want the route the user to page to select the account.

The following is my failed attempt:

    // within config

    $httpProvider.interceptors.push(function($q, $injector){
        return {
            'request': function(config) {
                var state = $injector.get('$state');

                if(state.is('user.list')) {
                    var accountService = $injector.get('AccountService');
                    if(!accountService.accountSelected()){
                        
                        // cancel the current request
                        var defer = $q.defer();
                        defer.resolve();
                        config.timeout = defer.promise;

                        state.go('account.select');

                    }
                }

                return config;
            }
        }
    });

This is causing an infinite loop for me. For some reason when state.go fires -- and it gets re-intercepted the state is still "user.list"

Note: I am using ui-router, angular 1.2.6

Another Note: The other place I thought of putting this was in a state.resolve block.

peterh
  • 11,875
  • 18
  • 85
  • 108
Jonathan
  • 16,077
  • 12
  • 67
  • 106

2 Answers2

4

do it like this

$injector.get('$state').transitionTo('public.login');

full code below

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

    function error(response) {

        if(response.status === 401) {
            $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);
harishr
  • 17,807
  • 9
  • 78
  • 125
  • so I am not sure this approach will work. I want to intercept the request -- not the response. also when I use transitionTo vs state.go I get the same behavior – Jonathan Apr 10 '14 at 16:30
  • 1
    that was just an example.. you can modify it for request/response... http://djds4rce.wordpress.com/2013/08/13/understanding-angular-http-interceptors/ – harishr Apr 10 '14 at 16:33
  • $injector.get('$state') is getting empty in my case, any clue ? – sandeep kale Mar 24 '15 at 11:45
1
  • I think you may want to try $location.path(destination) instead of $state.go(destination).
  • You'd better not put your redirect logic under 'request' block as accountService.accountSelected() may also make a request. here is the doc of $http interceptors
  • If you only have several routes which need to check account, it is better to put it in state.resolve block as you point out or put it in corresponding controller.
BenMorel
  • 34,448
  • 50
  • 182
  • 322
linkary
  • 123
  • 2
  • 4