4
votes

I'm using ui-router with nested states/views and I'm having a problem with the back button.

State hierarchy

  • product
    • personal
      • sub-cat-1
      • sub-cat-2
    • business
      • sub-cat-a
      • sub-cat-b
  • search

Problem

I initially load the page in state product.business.sub-cat-a. The top level page has a search input form which, when used, causes a state transition to state search (via a call to $state.go()) which all works fine.

However, if I click on the back button, I see the state transition from search to product.business.sub-cat-a as expected (via a call to $state.transitionTo()), but then there is an additional call to $state.go() back to state search and I can't work out where this call is coming from.

Would appreciate some help if anyone can shed some light on what ui-router is doing

Update

I've traced the problem down to the interaction between the urlRouter and $location. Seems $urlRouter.update sometimes pushes a url defined in a stat to $location and sometime pulls the value out of $location.

In this case, when things go wrong, the urlRouter location value is the old url which overwrites the $location.url value and causes the urlRouter to load the old state rather than the state we are trying to go back to.

The sequence seems to be:

  1. click back button
  2. browser loads the previous url from it's history
  3. ui-router goes about loading the correct state (the previous state)
  4. update is called on urlRouter (without read parameter) which causes $location to be reset to the pre-back button state url based on the urlRouter location value
  5. urlRouter then sees the two urls/states as different so it reloads the state now specified by $location.url which is the pre-back button url

So the problem seems to be that urlRouter location value isn't updated when the state is updated in step 3 above.

Any ui-router/angular experts, please feel free to point me in the right direction.

1
updated to angularjs v 1.2.27 but still experiencing the same problem - Peter Whitfield
seems like $location is being updated incorrectly by ui-router code although it may still be my fault. I'll update when I get to the bottom of it - Peter Whitfield

1 Answers

1
votes

For anyone who faces a similar problem, the issue here was that when the back button was pressed, two state transitions were triggered. The first was the correct one resulting from the back button; the second was a $state.go() associated with the parent (business) state as shown in the hierarchy above.

The second transition was processed before the promises generated by the resolve step had been resolved. This meant that the urlRouter location hadn't been updated before the subsequent $urlRoute.udpate() call and so the router reloaded the original page.

Hope this may help save someone else a day of debugging :-)