Infinite loop on ui-router $ stateChangeStart

Deployment on angular and ui-router

And struggling with redirection to another state if the precondition is not met:

I tried using an interceptor: ( How to create an angular interceptor predicate ).

But someone said that handling $ stateChangeState would be more appropriate. But I'm still running in an endless loop:

/** * Check here for preconditions of state transitions */ $rootScope.$on('$stateChangeStart', function(event, toState) { // which states in accounts to be selected var accountRequiredStates = ['user.list', 'user.new']; if(_.contains(accountRequiredStates, toState.name)){ event.preventDefault(); ApiAccount.customGET('get_current').then(function(resp){ // if I have a selected account, go about your business if(resp.hasOwnProperty('id')){ $state.go(toState.name); } else { // prompt user to select account $state.go('user.select_account'); } }) } }); 

Can anyone suggest a better sample (one that works)

Thanks!


Note. A similar problem is different from another: How do I pre-redirect in an angular interceptor

+5
source share
1 answer

I do not think that something is wrong with the general way that you are trying to do this, although I am not an expert. I see a flaw in the implementation, which looks as if it could cause an infinite loop. Say the user is trying to transition to the "user.new" state. Your listener $ stateChangeStart intercepts this, cancels it, does your customGET; then if the internal if condition is true ( resp.hasOwnProperty('id') ), you are trying to send the user to the same state as "user.new". At this point, your $ stateChangeStart listener intercepts it, cancels it, etc. Again and again.

How can I avoid this problem in my code, I need to have a variable (in the service where I declare the listener) to help me get around this check: var middleOfRedirecting = false; Inside the if block inside the resp.hasOwnProperty('id') check, set middleOfRedirecting to true; add a condition at the beginning of your listener $ stateChangeStart only to call event.preventDefault() and redirect if middleOfRedirecting is false. You will also need the $ stateChangeSuccess listener to set middleOfRedirecting back to false, resetting it for the next state change. (I feel that there must be a better way than this, but it at least works.)

+1
source

All Articles