17

I have the following states in my ui-router state provider:

$urlRouterProvider.when('/parent', '/parent/child');
$stateProvider.state('parent', {
     url: "/parent",
     abstract: true
});

$stateProvider.state('parent.child', {
     url: "/child"
});

Which follows the best practice for having a default child state as explained here in the ui-router docs.

However, when I now include a link in my document somewhere referencing parent with ui-sref such as <a ui-sref="parent">Link</a> I always get an error saying I cannot transition to an abstract state. When I enter the URL manually into the address bar and hit enter everything works fine.

Related Plunker: http://plnkr.co/edit/d3Z0tOwC3VCTPqGiB0df?p=preview

How can I combine ui-sref with default child states?

1
  • 2
    All abstract states require that you supply the template property with the value <ui-view/>, as the child template/Url plugs in to it. Now if you made a href with <a ui-sref="parent.child"> as @Chris-Preston suggested, your url bar would load /#/parent/child. This helped me out, link. At least if I understood that correctly. Someone let me know if I'm wrong :S
    – prasanthv
    Commented Nov 28, 2014 at 3:39

2 Answers 2

29

abstract states can not be targeted directly. They mainly serve as a foundation to build child states on. The only reason it works fine with the URL is that the /parent gets caught by the .when

That means when you invoke a child using

<a ui-sref="parent.child">

the child inside the parent gets loaded, meaning the parent will be loaded as the layer around it.

So, never target an abstract state itself. It's like having a door inside a door frame. You can only open and interact with the door (child), but never with the frame (parent) directly. However, when you interact with the door, the door and the frame are part of a system that gets loaded.

You can give the child an empty URL, so that it doesn't append anything to the parent state URL and will then be loaded.

See here for more info: https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#abstract-states

5
  • 4
    Sure I understand the limitations of an abstract state but thought that if it is possible to define a default child state it should also be possible to automatically forward all calls from the parent to the child (i.e. the logical behavior of ui-sref would be to forward to the default child state). In my case parent is currently abstract and not needed, but might later on become a page of itself (think overview page for an entire concept). But looks like that doesn't work well with ui-router.
    – Robin
    Commented Jul 26, 2014 at 11:14
  • as stated, giving the child state an empty URL you can access this child state using the parent's URL in the address bar. However, from the state of things, using ui-sref from the app itself you can only target the child directly Commented Jul 27, 2014 at 22:10
  • This should be marked as the answer and +1 for the link.
    – ceebreenk
    Commented Jan 13, 2015 at 8:22
  • Is it possible to have nested abstract states like grandparent.parent.child where grandparent and parent are abstract states ?
    – shruti
    Commented Mar 16, 2015 at 5:58
  • Since this is the case, how would one transition from a login state to an abstract dashboard state? Or is there another way to accomplish that?
    – Leon Gaban
    Commented Mar 14, 2017 at 18:42
1

If you want to use $state's convenient naming structure for abstract states, you can use this in a service:

$location.path(
    $state.href('app.some.abstract.state', { some: 'params' })
);

Or this in a template ($state must be available in the local or global $scope):

<a ng-href="{{$state.href('app.some.abstract.state', { some: 'params' })}}">...</a>

If I found myself doing this regularly, I would create a directive similar to ui-sref for this, minus the abstract state limitation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.