Matt Hintzke
Matt Hintzke

Reputation: 7984

ui-router navigation is occurring twice under certain conditions

I have a UI-Router site with the following states:

$stateProvider
    .state('order', {
        url: '/order/:serviceId',
        abstract:true,
        controller: 'OrderController'
    })
    .state('order.index', {
        url:'',
        controller: 'order-IndexController'
    })
    .state('order.settings', {
        url:'',
        controller: 'order-SettingsController'
    })

Where my two states do NOT have a url set, meaning they should only be reachable through interaction with the application. However the order.index state is automatically loaded by default because of the order in which I have defined the states.

I am noticing that trying to do a ui-sref="^.order.settings" or $state.go("^.order.settings") then ui-router first navigates to the order.settings state and then it immediately navigates to the order.index state (default state). I think this is happening because the url changing is causing a second navigation to occur and since the state.url == '' for both, it automatically defaults to the order.index state...

I tested this out by setting the {location: false} object in the $state.go('^order.settings', null, {location:false}). This caused the correct state to load (order.settings), but the url did not change. Therefore I think the url changing is triggering a second navigation.

Upvotes: 1

Views: 330

Answers (1)

Radim Köhler
Radim Köhler

Reputation: 123861

I'd understand, can imagine, that you do not like my answer, but:

DO NOT use two non-abstract states with same url defintion

This is not expected, therefore hardly supported:

.state('order.index', {
    url:'',                // the same url ...
    ...
})
.state('order.settings', {
    url:'',                // .. used twice
    ...
})

And while the UI-Router is really not requiring url definition at all (see How not to change url when show 404 error page with ui-router), that does not imply, that 2 url could be defined same. In such case, the first will always be evaluated, unless some special actions are used...

I would strongly sugest, provide one of (non default) state with some special url

.state('order.settings', {
    url:'/settings',       // ALWAYS clearly defined
    ...
})

Upvotes: 1

Related Questions