18

I have .when('/center', '/center/question') in my angular web app.

When I type '/center' in my browser it will redirect to '/center/question' as I expect but when I click the <a ui-sref="center" href="#/center"></a>, it won't redirect and just stay on the url '/center'.

There is no error in my console and I don't know why.

I see one similar issue here Angular UI-Router $urlRouterProvider .when not working anymore.I try the answer but it still don't work for me.

Here is my coffeescript code:

whenConfig = ['$urlRouterProvider', ($urlRouterProvider) ->
  # default url config

  $urlRouterProvider
  .otherwise '/center'
  .when '/center', '/center/question'
]

stateConfig = ['$stateProvider', ($stateProvider) ->
  # nested url config

  capitalize = (s)->
    s[0].toUpperCase() + s[1..]

  mainConfig = ({
    name: name
    url: "/#{name}"
    templateUrl: "templates/#{name}.html"
    controller: "#{capitalize name}Ctrl"
  } for name in ['center', 'keywordList', 'keywordConfig', 'log', 'stat'])

  centerConfig = ({
    name: "center.#{name}"
    url: "/#{name}?page"
    templateUrl: "templates/center/#{name}.html"
    controller: "Center#{capitalize name}Ctrl"
  resolve:
    thead: (CenterService) ->
      CenterService.getThead @self.name
    data: (CenterService, $stateParams) ->
      CenterService.fetchItems @self.name, $stateParams.page
  } for name in ['question', 'answer', 'comment', 'article'])

  for singleConfig in mainConfig
    $stateProvider.state singleConfig

  for childConfig in centerConfig
    $stateProvider.state childConfig
]

app.config whenConfig
app.config stateConfig
4
  • Don't need to add href="" in your <a> tag, this job will be handled by ui-router...So replace this line <a ui-sref="center" href="#/center"></a> to <a ui-sref="center"></a> and check Commented Nov 25, 2014 at 6:54
  • @Asik I don't add href="", this is added by ui-router Commented Nov 25, 2014 at 7:18
  • oh Ok sorry! I misunderstood Commented Nov 25, 2014 at 7:34
  • Try adding a breakpoint at line 3224 of ui-router in your browser and check if the transition promise is swallowing a syntax error or something. I've had that happen a few times. Commented Nov 25, 2014 at 12:10

2 Answers 2

21

There is a new working plunker (extending the Angular UI-Router $urlRouterProvider .when not working *anymore*), which should be working with the version 0.2.13+

Previous solution

Until version 0.2.12- we could use $urlRouterProvider.when(), suggested in documenation (small cite):

How to: Set up a default/index child state

...
if you want the 'parent.index' url to be non-empty, then set up a redirect in your module.config using $urlRouterProvider:

 $urlRouterProvider.when('/home', '/home/index');

So this was solution shown in the Q & A mentioned above:

var whenConfig = ['$urlRouterProvider', function($urlRouterProvider) {

    $urlRouterProvider
      .when('/app/list', ['$state', 'myService', function ($state, myService) {
            $state.go('app.list.detail', {id: myService.Params.id});
    }])
    .otherwise('/app');
}];
...
app.config(whenConfig) 

Now - we cannot.

UI-Router "FIX" in 0.2.13

It is due to "FIX" (which I am simply not sure about), mentioned in the release 0.2.13

Bug Fixes
$state:
- ...
- Avoid re-synchronizing from url after .transitionTo (b267ecd3, closes #1573)

And here is the new code added in the urlRouter.js:

if (lastPushedUrl && $location.url() === lastPushedUrl)
 // this line stops the corrent .when to work
 return lastPushedUrl = undefined;

lastPushedUrl = undefined;

This piece of code is optimizing/fixing some other issue ... but also, turning off the .when() functionality

SOLUTION

As already mentioned, this brand new plunker shows the way with version 0.2.13+. We just have to listen to state change, and if the state is "app.list" we can go to its detail with some id...

var onChangeConfig = ['$rootScope', '$state',
 function ($rootScope, $state) {

  $rootScope.$on('$stateChangeStart', function (event, toState) {    
    if (toState.name === "app.list") { 
      event.preventDefault();
      $state.go('app.list.detail', {id: 2});
    }
  });

}]

Check the plunker here

Sign up to request clarification or add additional context in comments.

4 Comments

You should also know, that because I am not sure, if this "new" behaviour of 0.2.13 is correct, I issued an issue github.com/angular-ui/ui-router/issues/1584. It could be that this workaround will be the way, but maybe not... we will see ;) Good luck with awesome UI-Router ;)
Got it ! Actually I also hope this could be more elegant, I subscribe the issue, thanks any way :)
UI-Router dev here. J22Melody, is your use case that you essentially want "a default substate of an abstract state?" @RadimKöhler I'm considering your issue. I'll likely roll that commit back for 0.2.x (since it is what people currently expect), but reintroduce it in a later version when we have a better state-based-redirect solution.
@ChrisT Yes, I want "a default substate"
3

You can do this in your controller too. I think it is cleaner than listening to state changes.

Example:

.controller 'YourControllerName', ($scope, $state) ->
    $state.go "center.question" if $state.is "center"

2 Comments

Am I the only one thinking CoffeeScript is completely unreadable?
This will only fire once when the controller is first initialised, but it will not be fired again and hence doesn't fix the problem. With this solution visiting centre will redirect to center.question but clicking a ui-srefof center will navigate to center without firing the above code again, leaving you in a blank view.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.