1

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.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Matt Hintzke
  • 7,744
  • 16
  • 55
  • 113

1 Answers1

1

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
    ...
})
Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Is there any built in way through ui-router to achieve the functionality I am looking for then? I would prefer not to have a url change when these 2 states are active. Should I use basic AngularJS directives to achieve this instead? I was hoping it could be made state-based\ – Matt Hintzke Nov 20 '14 at 06:13
  • I am trying to explicitly say: "there is NO built in way through ui-router", because that is not expecte, not intended by state machine. States should be unique, by their url *(or in some cases do not use url at all)*. I thought you won't love my answer... sorry – Radim Köhler Nov 20 '14 at 06:16
  • Sorry I just did not fully understand what you were trying to say. I figured this scenario is needed frequently (App in App type of design) where you wanted state-like navigation and browser history – Matt Hintzke Nov 20 '14 at 06:25
  • *Wish to have "the answer"...*, enjoy the `UI-Router` anyhow. It is bloody fantastic tool ;) – Radim Köhler Nov 20 '14 at 06:32
  • See this issue: https://github.com/angular-ui/ui-router/issues/1573 -- one-to-one mappings between states and URLs will fix this. double transitions are caused when the mapping is not one-to-one. I believe 0.2.13 release should allow you to use $state.go() to states which match multiple URLs. However, a browser refresh will not necessarily map back to the state you .go()'d to. – Chris T Nov 20 '14 at 18:25