1

I'm building a small Angular app and I'm currently using ui-router.

I've hit a problem which looks awfully like a bug in ui-router but I can't be sure as I'm not that familiar with this library. When the user clicks on a specific link, although the correct view state gets loaded as expected, the URL in the address bar doesn't get updated.

I'm using ui-router's ui-sref directive to automatically generate the URL for the state. For example in the checklist list view I use the following code:

<a ui-sref="checklist-phase({ aircraftId: checklist.aircraft, checklistId: checklist.id, phaseSlug: checklist.phases[0].slug })" ng-bind="checklist.name"></a>

I've cut down my app and made it into a Plunker so the problem is hopefully reproducible by others. The issue can also be observed in this video: https://www.youtube.com/watch?v=EW9CFe6LfCw

Reproduction steps:

  1. Go to http://run.plnkr.co/plunks/ZqMIYNU6abEAndAM5nx1/#/aircraft/1/checklists
  2. Click the first link. Notice that the view updates to show the correct state, but the URL remains at /#/aircraft/1/checklists.

What is strange is that navigating back to this state by other means updates the URL perfectly. For example (assuming steps 1 and 2 above have been followed):

  1. Scroll to the bottom and click the Next Phase link. Note that the state changes and the URL updates.
  2. Scroll down on this new view and click Previous Phase. Note that the previous state reloads and this time the URL it updated correctly.

Am I using ui-router incorrectly or doing something else incorrectly to cause this behaviour?

Wills Bithrey
  • 13
  • 1
  • 4
  • I'm not sure whats happening, but instead of specifying parent in the `$stateProvider.state(...)` function, I always specify the parent in the state name itself. like `'checklist-detail.checklist-phase'`. Don't know if this will fix the problem, but your app could benefit from this. Your state names could become `checklists`, `checklists.detail`, `checklists.detail.phase` and so forth. – Ben Wilde Jul 28 '14 at 20:35

1 Answers1

1

Check here updated version

On your state 'check-lists' you provide ui-sref to 'checklist-phase'

<a ui-sref="checklist-phase({ aircraftId: ...

And the 'checklist-phase' is defined as a child state of 'checklist-detail'

.state('checklist-phase', {
    parent: 'checklist-detail',

And the state 'checklist-detail' has controller which calls $state.go

.state('checklist-detail', {       
    controller: 'ChecklistDetailCtrl',
    ...

    .controller('ChecklistDetailCtrl', function ($scope.... 
    {

        $state.go('checklist-phase', {
            phaseSlug: checklistData.phases[0].slug
        }, {
            location: 'replace'
        });

Do NOT do that... just remove the $state.go - because you are already navigating to the checklist-phase (see the first lines above) ... check it here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Oops. I totally forgot I had a call to $state.go in the controller. It didn't occur to me that could be the cause. Thanks! The reason that $state.go call is there was to try and redirect a visit to `/aircraft/:aircraftId/checklist/:checklistId` to `/aircraft/:aircraftId/checklist/:checklistId/phase/:firstPhaseSlug` so that the URL structure didn't seem broken. Is there a way to achieve this without breaking the checklist-detail state as I did in the original question? – Wills Bithrey Jul 29 '14 at 17:32
  • Wish to help you, but not sure if I understand... what my updated plunker shows is workign solution... is not it? Do you need something else? because, the `ui-sref` is enough. It is in fact the same as the $state.go(). Other words, I am not sure what is still not .... as you like ;) – Radim Köhler Jul 29 '14 at 17:47
  • Yes your solution solves the problem :). In my previous comment I was explaining why I used the $state.go function. I was fully aware that ui-sref used it internally to actually do the routing. My call to $state.go was to try and catch the case of the user visiting a URL like: `http://run.plnkr.co/plunks/8bra44NhzbTP05puorAZ/#/aircraft/1/checklist/1/`. Currently hitting this URL just redirects to the aircraft screen. I was trying to make the app redirect to the correct first phase automatically in this situation. – Wills Bithrey Jul 29 '14 at 19:10