0

I'm using angular1.4,ui.router0.2.15. Trying to redirect to login state in $stateChangeStart. Here's the logic:

$rootScope.on('$stateChangeStart', function(){
  if(!isLoggedIn && toState.name !== 'login') {
    console.log('go to login');
    e.preventDefault();
    $state.go('login');
  } else if (isLoggedIn && toState.name === 'login') {
    console.log('go to home');
    e.preventDefault();
    $state.go('home');
  } else {
    console.log('no change');
  }
});

I thought the execution will be like:

event1: from:'', to:'home', 'go to login' 
event2: from:'', to:'login', 'no change' 
...then proceed

But in fact it is:

event1: from:'', to:'home', 'go to login' 
event2: from:'', to:'login', 'no change'
event3: from:'', to:'home', 'go to login'
event4: from:'', to:'login', 'no change',
event5: from:'', to:'home', 'go to login',
...the dead loop continues until max digest loop

I spotted that event3 is trigger in angular-ui-router.js function registerState:

// Register the state in the global state list and with $urlRouter if necessary.
    if (!state[abstractKey] && state.url) {
      $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {
        if ($state.$current.navigable != state || !equalForKeys($match, $stateParams)) {
          $state.transitionTo(state, $match, { inherit: true, location: false });
        }
      }]);
    }

But I lost track of the problem since it's too complicated.

Why event3 fired??? And if I wanted my redirection should I register my own event like $myStateChangeStart???

addlistener
  • 871
  • 1
  • 12
  • 20
  • I'd say that all that is covered here http://stackoverflow.com/a/26702638/1679310 – Radim Köhler Oct 19 '15 at 10:44
  • @RadimKöhler Are you saying register $stateChangeStart in app.run is not recommended? I checked $state.current in app.run is { "name": "", "url": "^", "views": null, "abstract": true } – addlistener Oct 19 '15 at 10:53
  • @RadimKöhler The problem is not I redirect to login twice but an invisible $state.transitionTo fired in ui.router itself... – addlistener Oct 19 '15 at 10:58
  • In the link I gave you is a plunker, which is working. I would suggest to compare that with your stuff. UI-Router behaviour is expectable.. no invisible transitions, I'd say – Radim Köhler Oct 19 '15 at 11:01
  • @RadimKöhler I've heard urlRouterProvider does not work well with ui.router. And the problem here is exactly an invisible state transition fired by urlRouterProvider, if you look at the last piece of code in the question(also https://github.com/angular-ui/ui-router/blob/master/release/angular-ui-router.js#L2346 ). And ui.router actually fires another invisible transitionTo in its handleRedirect function(https://github.com/angular-ui/ui-router/blob/master/release/angular-ui-router.js#L2927). – addlistener Oct 19 '15 at 11:13
  • @RadimKöhler And the first transitionTo ever is fired by that urlRouterProvider line, from '' to 'home'. It seems a '' to 'home' transition is fired again by urlRouterProvider(Apparently not me). – addlistener Oct 19 '15 at 11:28
  • Sorry, I do not have another answer for you. That's why I added just a comment – Radim Köhler Oct 19 '15 at 11:32
  • @RadimKöhler that's why I love stackoverflow and all the enthusiastic people like you :) – addlistener Oct 19 '15 at 12:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92728/discussion-between-jchnxu-and-radim-kohler). – addlistener Oct 19 '15 at 12:46

1 Answers1

0

I don't really understand what is the mechanism of ui.router. But I hacked it like doing the initial route change(aka. state '' to state 'home') not in the handler. But somewhere else. It seems to me the problem occurs only when the app first bootstraps.

Steps:

1.Make a root abstract state, doing the same redirection logic of the $stateChangeStart handler.

2.Add

if(!from.name) {
    return;
}

to the beginning of the $stateChangeStart handler.

addlistener
  • 871
  • 1
  • 12
  • 20