Search code examples
angularjsangular-ui-routersingle-page-applicationangularjs-rootscope

AngularJS on $stateChangeStart loop


In a web application I want that, when the user route in the $state, Angular checks if there is a token and if he has permission. But I have a problem: even if I do event.preventDefault(), it starts a loop and browser crashes. How can i prevent this loop and let user goes or block the navigation?

code:

  .run(function ($rootScope, $window, $state, Auth) {
  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, $window) {

// Easy case that doesn't loop: just 'return'
if (toState.name === 'login' ){
    // doe she/he try to go to login? - let him/her go
    return;
}

if (Auth.isLoggedIn && $window.localStorage.identityToken) {

  var requiredAdmin = toState.data.requiredAdmin; 
  if (requiredAdmin && $window.localStorage.isAdmin){
    $state.go(toState.name); // it starts the loop
  } else { // if he is logged but has no permission, stop the navigation
    $state.go(fromState.name); // it starts the loop
  }

  return;
}

});

Solution

  • You should make your check on the higher state and not on every state change so if you have routes like /login, /secured, /secured/.... you make your checks on the resolve clause of the /secured state otherwise your logic will execute on every state change and that is not the right approach for authentication/authorization process.

    https://github.com/angular-ui/ui-router/wiki.

    this way you make your check only once on the child paths.