Search code examples
angularroutesangular7router-outlet

Angular auxiliary routes with named router-outlets: ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment


I am having a hard time getting auxiliary routes to work, even in a minimalistic scenario. I'm pretty sure, I stuck to the angular documentation on routes and multiple outlets down to a T, so I really have no idea what I am missing.

app.routing.ts:

const appRoutes: Routes = [
  {
    path: '',
    children: [
      // aux route with named outlet, **DOES NTO WORK :(**
      {
        path: 'simple',
        component: SimpleComponent,
        outlet: 'simpleOutlet'
      },

      // default route, *WORKS*
      {
        path: '',
        component: AppComponent
      },
      // fallback route, *WORKS*
      {
        path: '**',
        component: AppComponent,
        redirectTo: ''
      }
    ]
  }
];

app.component.html:

<h2>I am the app component</h2>
<router-outlet></router-outlet>
<router-outlet name="simpleOutlet"></router-outlet>

Before using routerLink, I wanted to get it to work by entering a URL right into the browser. Is it possible, that I missed something crucial regarding navigating to aux routes by direct URL? Here's what happens when directly hacking in URLS:

  • http://localhost:4200/ works; app.component.html is displayed
  • http://localhost:4200/somethingfallback123 works; due to the fallback-route, app.component.html is displayed
  • http://localhost:4200/(simpleOutlet:simple) does not work neither does http://localhost:4200(simpleOutlet:simple), http://localhost:4200/(simpleOutlet:/simple), http://localhost:4200/(simpleOutlet:simple/) etc.. (you can see, I am desperate)

Stackblitz link


ERROR LOGS:

Mozilla Firefox:

ERROR Error: "[object Object]"
resolvePromise http://localhost:4200/polyfills.js:7882:31
resolvePromise http://localhost:4200/polyfills.js:7839:17
scheduleResolveOrReject http://localhost:4200/polyfills.js:7941:17
invokeTask http://localhost:4200/polyfills.js:7489:17
onInvokeTask http://localhost:4200/vendor.js:70021:24
invokeTask http://localhost:4200/polyfills.js:7488:17
runTask http://localhost:4200/polyfills.js:7256:28
drainMicroTaskQueue http://localhost:4200/polyfills.js:7663:25

It seems to be a know issue that Firefox does not throw correct error messages.

Google Chrome:

ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL             Segment: 'simple'
Error: Cannot match any routes. URL Segment: 'simple'

Environment (angular version: ng v)

Angular CLI: 7.0.4
Node: 9.7.1
OS: linux x64
Angular: 7.0.2

Solution

  • here the code to solve this issue StackBlitz

    in app.routing.ts

    instead

    const appRoutes: Routes = [
      {
        path: '',
        children: [
          // aux route with named outlet, **DOES NTO WORK :(**
          {
            path: 'simple',
            component: SimpleComponent
          },
    
          // default route, *WORKS*
          {
            path: '',
            component: AppComponent
          },
          // fallback route, *WORKS*
          {
            path: '**',
            component: AppComponent,
            redirectTo: ''
          }
        ]
      }
    ];
    

    do

    const appRoutes: Routes = [
      {
        path: 'main',
        component: AppComponent,
        children: [
          // aux route with named outlet, **DOES NTO WORK :(**
          {
            path: 'simple',
            component: SimpleComponent,
            outlet: 'simpleOutlet'
          }
        ]
      }
    ];
    

    and instead

    exports: [RouterModule, appRoutes]
    

    do

    exports: [RouterModule]
    


    in app.component.html

    instead

    <h1>
      app component
    </h1>
    
    <router-outlet></router-outlet>
    

    do

    <h1>
      app component
    </h1>
    
    <router-outlet></router-outlet>
    <router-outlet name="simpleOutlet"></router-outlet>
    


    in app.module.ts

    remove import { Routes, RouterModule } from '@angular/router'; you not need it here you already made a separated Routing file

    add

    import { AppRoutingModule } from './app.routing';
    import { SimpleComponent } from './simple/simple.component';
    

    instead

    @NgModule({
      imports:      [
        BrowserModule,
        FormsModule,
        RouterModule.forRoot([])
      ],
      declarations: [ AppComponent, HelloComponent ],
      bootstrap:    [ AppComponent ]
    })
    

    do

    @NgModule({
      declarations: [ AppComponent, HelloComponent, SimpleComponent ],
      imports:      [
        BrowserModule,
        FormsModule,
        AppRoutingModule
      ],
      bootstrap:    [ AppComponent ]
    })
    

    do that as following declarations then imports the order is important as long you made a separated routing file

    for more details and reference take a look on the link mentioned above.