Reputation: 218
Angular 1.6.1 and ui-router 1.0.0rc;
I'm running into an issue with ui-router while redirecting from one state to another.
A TransitionRejection
is registered because it's superseded.
Transition #1 r0: Started -> "Transition#1( 'intro'{} -> 'foo'{} )"
Transition #1 r0: <- Rejected "Transition#1( 'intro'{} -> 'foo'{} )", reason: TransitionRejection(type: 2, message: The transition has been superseded by a different transition, detail: 'bar'{"id":"uuid-1234-uuid"})
Transition #2 r0: Ignored <> "Transition#2( 'intro'{} -> 'intro'{} )"
Transition #3 r0: Started -> "Transition#3( 'intro'{} -> 'bar'{"id":"uuid-1234-uuid"} )"
Transition #3 r0: <- Success "Transition#3( 'intro'{} -> 'bar'{"id":"uuid-1234-uuid"} )", final state: bar
Note: globally there's a catch all, it's used for auth control when a user does not resolve when loading a state:
// state 'intro' is '/'
.config($urlRouterProvider => {
$urlRouterProvider.otherwise('/');
})
.run(($transitions, $trace) => {
$trace.enable('TRANSITION');
$transitions.onError({}, trans => trans.router.stateService.go('intro'));
}
The transition snippet
// there is no foo component, it's a straight redirect
.component('bar', {
template: someTemplate,
controller: someCtrl
})
.config($stateProvider => {
let states = [
{
name: 'foo',
url: '/foo',
redirectTo: { state: 'bar', params: { id: 'uuid-1234-uuid' } }
},
{
name: 'bar',
url: '/bar/:id',
component: 'bar'
}
];
states.forEach(s => $stateProvider.state(s));
})
While in this example of intro -> foo
eventually it ends up in the correct state bar
, other transitions (when not going from intro(default)
to bar
, but from baz, qux, ..
to bar
) end up in an endless transition loop.
For example, going from qux
to foo
, which should redirect to bar
, but gets caught in a qux -> intro
loop: (I don't have earlier error messages of qux -> foo
because the browser crashes)
TransitionRejection(type: 2, message: The transition has been superseded by a different transition, detail: Transition#2704( 'qux'{} -> 'intro'{} ))
Does anyone have a solution to the redirect, or can see if I'm using the global catch-all correctly? Catch all is causing the death loop, but that's secondary to the problem of redirect-reject that triggered it in the first place.
Upvotes: 4
Views: 10804
Reputation: 603
Transition superseded error occurs when you try to trigger a state change before previous state change event has completed. A simple way to solve this problem is by calling the state change after a timeout. Which allows current state change to be completed and then triggers the next state change.
$timeout(function(){
$state.go('statename')
})
Note: The timeout here has no defined time, that simply means it will be executed after all current processes are done
Upvotes: 13
Reputation: 1
In version 1.0.20 use trans.router.stateService.target('sth') instead of $state.go('sth)
Upvotes: 0
Reputation: 412
If you return a target state from the transition hooks instead of using stateService.go, then this problem should go away as far as my current understanding of ui-router goes.
Upvotes: 0