Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6.1.9 nested routing to named outlets - 'Cannot match any routes' error

I use Angular 6.1.9 with its router module. It seems impossible for me to route/display a named outlet content.

When calling <a [routerLink]="['', { outlets: { editArea: ['addRootPartner'] } }]">foo</a> it crashes with:

NavigationError(id: 2, url: '/overview/work/allPartners(editArea:addRootPartner)', error: Error: Cannot match any routes. URL Segment: 'addRootPartner')


My app structure is:

app.module
app-routing.module

workspace.module
workspace-routing.module

app-routing:

const rootAppRoutes: Routes = [
  { path: '',  redirectTo: 'overview', pathMatch: 'full' },
  { path: 'overview', loadChildren: './overview/workplace/workplace.module#WorkplaceModule' },
  { path: '**', component: PageNotFoundComponent }
];

Redirects to the overview which loads the workplace module.

workplace-routing:

const workplaceRoutes: Routes = [
  { path: '', redirectTo: 'work', pathMatch: 'full'},
  { path: 'work', component: WorkplaceComponent, children: [
    { path: 'allPartners', component: RootPartnersComponent },
    { path: 'childPartners', component: ChildPartnersComponent },
    { path: '', redirectTo: 'allPartners', pathMatch: 'full'}
  ]},
  { path: 'addRootPartner', component: AddRootPartnerComponent, outlet: 'editArea' }
];

Redirects to work which displays the WorkplaceComponent. Then it goes further to child allPartners which displays RootPartnersComponent.


In the code I use two <router-outlet>s. One is inside a component app module:

<router-outlet></router-outlet>

The second is in the workplace module, WorkplaceComponent:

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

What is wrong with this setup? Is there a technical restriction on usage of nested named outlets?

like image 470
Yuri Avatar asked Oct 03 '18 16:10

Yuri


1 Answers

Okay, after a night spent with this mess, I found a solution.


First, the named outlet child routes don't work when defined under a parent with path: ''...

// the root redirect due to named outlets not being able to work as children of "path: ''"
{ path: '', redirectTo: 'work', pathMatch: 'full' },
{ path: 'work', component: WorkplaceComponent, children: [
   { path: '', component: RootPartnersComponent, outlet: 'displayArea' },
   { path: 'childPartners', component: ChildPartnersComponent, outlet: 'displayArea' },
   // child for edit area outlet
   { path: 'addRootPartner/:id', component: AddRootPartnerComponent, outlet: 'editArea' }
]}

https://blog.angular-university.io/angular-2-router-nested-routes-and-nested-auxiliary-routes-build-a-menu-navigation-system/


Second issue was related to the router link. Apparently, you have to specify your parent route as the base of navigation. Thus navigation has to be done programmatically.

this.router.navigate([
  // NOTE: No relative-path navigation is required because we are accessing
  // the parent's "activatedRoute" instance. As such, this will be executed
  // as if we were doing this in the parent view component.
  {
    outlets: {
      editArea: ['addRootPartner']
    }
  }
],
  {
    relativeTo: this.activatedRoute.parent // <--- PARENT activated route.
  }
);

https://www.bennadel.com/blog/3351-closing-secondary-router-outlet-views-from-within-the-named-route-view-components-in-angular-4-4-4.htm


Super late edit:

The issue with path: '' might be caused by configuring this route as the first one.

The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes. In the configuration above, routes with a static path are listed first, followed by an empty path route, that matches the default route. The wildcard route comes last because it matches every URL and should be selected only if no other routes are matched first.

angular.io/guide/router

like image 118
Yuri Avatar answered Nov 16 '22 16:11

Yuri