angularangular-routerangular-module

Angular component won't load in default outlet using an empty path, but will with an outlet name


I have a few router outlets in my app component. All except one have a name.

<router-outlet name="menu"></router-outlet>
<router-outlet></router-outlet>
<router-outlet name="sidebar"></router-outlet>

Currently, my root route config specifies the following:

[
  {
    path: 'mypath',
    loadChildren: () => import('./my-main.module').then((m) => m.MyMainModule)
  }
]

The lazy-loaded 'main module' route config looks like this:

[
  {
    path: ':myMainId',
    resolve: { myMainData: MyMainDataResolver },
    children: [
      {
        path: ':mySubId',
        resolve: { mySubData: MySubDataResolver },
        loadChildren: () =>
          import('./my-sub.module').then((m) => m.MySubModule) // Needs mySubData
      },
      { path: '', component: MyMainComponent } // Needs myMainData
    ],
  },
  { path: '', component: MenuComponent, outlet: 'menu' }
]

And finally, my lazy-loaded 'sub module' route config looks like this:

[{ path: '', component: MySubComponent, outlet: 'sidebar' }]

Using the above configuration, my MyMainComponent does not load (constructor/onInit not called). However, if I give the default router-outlet a name and specify the outlet name for MyMainComponent's route in the route config, all of the components render.

Similarly, if I drop the :mySubId segment of the url, and leave the main outlet nameless, the MyMainComponent does render.

So, some sort of conflict seems to be happening between MyMainComponent's route and MySubComponent's route (or its parent).

I suspect it has something to do with both of those routes being empty and perhaps both somehow matching, but I don't see how that could be when one has an outlet name specified and the other does not.

Thanks in advance for any help you can provide.


Solution

  • In order to achieve what I was after, I had to duplicate the MyMainComponent route config into a sibling of the MySubComponent route config:

    [
      {
        path: '',
        component: MyMainComponent,
      },
      { 
        path: '', 
        component: MySubComponent, 
        outlet: 'sidebar' 
      }
    ]
    

    This allows the main component to load within the default router-outlet in the following two scenarios, which is what I was ultimately after:

    http://mypath/mymainid
    
    http://mypath/mymainid/mysubid
    

    I was under the impression that MyMainComponent should match the empty path regardless of whether it was defined as part of the child path or not, but I was wrong. In my opinion, however, I think that it should, or that there should be some sort of option to allow it to do so, because having to configure it twice like I now have feels weird.