In my music app, I have an ng-repeat on the top-level states of my app to create navigation links. One of the top-level states, called library, is abstract and has child states (which are navigable using tabs). Since I am using an ng-repeat, the abstract state has a directive of ui-sref="library". However, it's not possible to navigate to an abstract parent state like that, instead I would need to write ui-sref="library.albums". I am unable to do this because of the ng-repeat data coming directly from the state provider. How can I set a default child state on "library" so that whenever that state is visited, it redirects to the child?
 
    
    - 1,340
- 2
- 25
- 41
- 
                    Possible duplicate of http://stackoverflow.com/questions/20598000/have-parent-state-default-to-child-state-using-ui-router – Zdenek Hatak Aug 05 '16 at 22:10
3 Answers
Found this question when I was looking for the same and then I found this on Angular UI-Router's FAQ page. https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions
How to: Set up a default/index child state
- Make the parent state abstract. - $stateProvider .state('library', { url: '/library', abstract: true, template: '<ui-view></ui-view>' }) .state('library.albums', { url: '/albums', template: '<h1>Albums</h1>' });
- Then if you give the child state an empty URL, it will match the exact parent's URL. However, if you want to keep a separate URL for the child, you can do this: - $urlRouterProvider.when('/library', '/library/albums');
Read the given GitHub WIKI URL if you need more information.
 
    
    - 335
- 4
- 13
Unfortunately you can't use ui-sref to link to an abstract state.
you could try something like:
$rootScope.$on('$stateChangeStart', function(event, toState, toParams){
    if(toState.name == 'library'){
        event.preventDefault();
        $state.go('library.albums', toParams);
    }
}
Rather than hardcoding each state redirection though, you could do something like:
$stateProvider
    .state('library', {
        url: '/library',
        data: {
            redirect: 'library.albums'
        }
    })
    .state('library.albums', {
        url: '/albums',
        data: {
            redirect: false
        }
    });
$rootScope.$on('$stateChangeStart', function(event, toState, toParams){
    if(toState.data && toState.data.redirect){
        event.preventDefault();
        $state.go(toState.data.redirect, toParams);
    }
}
 
    
    - 2,140
- 1
- 19
- 18
- 
                    I am using 0.3.1 version of ui-router. And I don't know why but these solutions didn't work for me. Both of them! – Hussain Nov 06 '16 at 17:46
- 
                    1If you use `toState.data.hasOwnProperty('redirect')` you won't need to do `redirect:false` on each state that doesn't redirect – ioneyed Apr 03 '17 at 17:26
In V1.0 of ui-router, the state parameter redirectTo was added (see ui-router docs). This allows you to accomplish what you are looking for.
In your example you would not use abstract: true but would redirect to the library.albums state.
$stateProvider
    .state('library', {
        url: '/library',
        redirectTo: 'library.albums',
        template: '<ui-view></ui-view>',
       
    })
    .state('library.albums', {
        url: '/albums',
        template: '<h1>Albums</h1>'
    });
with this you can use ui-sref="library". This is very helpful because ui-sref-active will now work.

 
    