Billiam
Billiam

Reputation: 218

Angular ui-router 1.0.0rc transition superseded on a redirect

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

Answers (3)

kartik
kartik

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

Hossein Rezaei
Hossein Rezaei

Reputation: 1

In version 1.0.20 use trans.router.stateService.target('sth') instead of $state.go('sth)

Upvotes: 0

Chaudhry Junaid
Chaudhry Junaid

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

Related Questions