1

I'm trying to redirect an AngularJS app in the case that the requested state requires login. This is the method I've placed within the 'run' method on my angular app:

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {

  if(toState.data.requiresLogin && !User.isLoggedIn)
  {
    event.preventDefault();
    $state.go('login');
  }
});

Seems straightforward, but I'm getting this digest error. It appears to be triggered by the event.preventDefault() statement. I can't remove that of course...

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 7; oldVal: 6"],["fn:     $locationWatch; newVal: 8; oldVal: 7"],["fn: $locationWatch; newVal: 9; oldVal: 8"],["fn: $locationWatch; newVal: 10; oldVal: 9"],["fn: $locationWatch; newVal: 11; oldVal: 10"]]
...

Any advice on how to refactor this to clear this error, or what the error even means?

Shawn McBride
  • 542
  • 1
  • 4
  • 13
  • Have a look at this blog post it does exactly what you need http://jonsamwell.com/url-route-authorization-and-security-in-angular/ – Jon Jul 12 '14 at 05:01

1 Answers1

1

There is a working example, how to redirect to login. Firstly there are 4 states defined - 2 of them require authentication, third is public (for anybody) and there is also login state:

$stateProvider
    // available for anybody
    .state('public',{
        url : '/public',
        template : '<div>public</div>',
    })
    // just for authenticated
    .state('some',{
        url : '/some',
        template : '<div>some</div>',
        data : {requiresLogin : true },
    })
    // just for authenticated
    .state('other',{
        url : '/other',
        template : '<div>other</div>',
        data : {requiresLogin : true },
    })
    // the log-on screen
    .state('login',{
        url : '/login',
        templateUrl : 'tpl.login.html',
        controller : 'UserCtrl',
    })

and that would be the $stateChangeStart def, which always redirects to login - if required ... only login itslef and public are available always/to anybody

.run(['$rootScope', '$state', 'User', function($rootScope, $state, User)
{

  $rootScope.$on('$stateChangeStart'
    , function(event, toState, toParams, fromState, fromParams) {

    var isAuthenticationRequired =  toState.data 
          && toState.data.requiresLogin 
          && !User.isLoggedIn
      ;

    if(isAuthenticationRequired)
    {
      event.preventDefault();
      $state.go('login');
    }
  });
}])

Check that all in action here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335