Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 router doesn't resolve child auxiliary route

I'm trying to use an auxiliary route for a modal window. Regardless of what I try I can't get it to resolve. I just get routing errors. Here's my approach...

app.component.html

<router-outlet></router-outlet>
<router-outlet name="modal"></router-outlet>

admin-routing.module.ts

...
const ROUTES: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    children: [
      {
        path: 'accounts',
        loadChildren: './accounts/accounts.module#AccountsModule'
      },{...}
    ]
  }
];
...

accounts-routing.module.ts

...
const ROUTES: Routes = [
  {
    path: '',
    children: [
      {
        path: '',
        component: AccountsIndexComponent
      },{
        path: 'new',
        component: AccountsNewComponent
      },{
        path: ':id',
        component: AccountsShowComponent
      },{
        path: ':id/edit',
        component: AccountsEditComponent,
        outlet: 'modal'
      }
    ]
  }
];
...

modal.service.ts

  ...
  constructor(
    private router:Router,
    private route:ActivatedRoute
  ) { }
  open(route:Array<any>) {
    this.router.navigate(
      [{outlets: {drawer: route}}], {relativeTo: this.route}
    )
  }
  ...

When I call the ModalService.open([account.id, 'edit']) it tries to navigate to /admin/accounts(modal:1/edit) which is what I think it's supposed to do. But I just get an error that it can't match the 1/edit url segment.

NavigationError(id: 2, url: '/admin/accounts(modal:1/edit)', error: Error: Cannot match any routes. URL Segment: '1/edit')

I've tried the following and they didn't work either...

ModalService.open(['accounts', account.id, 'edit'])
ModalService.open(['admin','accounts', account.id, 'edit'])
like image 915
Brian Avatar asked Feb 09 '17 22:02

Brian


1 Answers

It seems that there is a known bug in the router that prevents child auxiliary routes from being loaded when the parent path is empty, which is what you are doing in accounts-routing.module.ts:

const ROUTES: Routes = [
  {
    path: '',                 // <--- cannot have an empty parent path...
    children: [
      {
         path: ':id/edit',
         component: AccountsEditComponent,
         outlet: 'modal'      // <--- ...with child aux outlet
      }
    ]
  }
]

To work around the issue, we must supply something for the path. For instance, if you name your path 'accounts':

const ROUTES: Routes = [
  {
    path: 'accounts', 
    ...

then you can navigate to your aux route either from a routerLink:

<a [routerLink]="['accounts', {outlets: {'modal': ['1/edit']}}]">

or programatically:

this.router.navigateByUrl('accounts/(modal:1/edit)')

Here is a working Plunkr I made to figure this out and demonstrate successfully loading a child auxiliary route.

like image 178
Mike Chamberlain Avatar answered Nov 19 '22 09:11

Mike Chamberlain