Sourabh Dev
Sourabh Dev

Reputation: 743

Angular2 second level child routing to root insteead of first child

I am trying to create a multilevel routing hierarchy. Something like this:

app

 |---core

       |---items

My app router and html are as follows:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
    {path: 'core', loadChildren: 'app/core/core.module#CoreModule'}
];

@NgModule({
    imports: [
        RouterModule.forRoot(routes)
    ],
    exports: [
        RouterModule
    ],
    providers: [
    ]
})
export class AppRoutingModule { }

HTML:

<h1>
    {{title}}
</h1>
<router-outlet></router-outlet>

My core route and html are as follows:

import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router';

import { CoreComponent } from './core.component';

const coreRoutes:Routes = [
    {path: 'item', loadChildren: 'app/core/item/item.module#ItemModule'},
    {path: '', component: CoreComponent}

];

@NgModule({
    imports: [RouterModule.forChild(coreRoutes)],
    exports: [RouterModule] }) export class CoreRoutingModule { }

HTML:

core module
<router-outlet></router-outlet>

And finally the item route and html are as follows:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { ItemComponent } from './item.component';

const itemRoutes:Routes = [
    {path: '', component: ItemComponent}
];

@NgModule({
    imports: [RouterModule.forChild(itemRoutes)],
    exports: [RouterModule]
})
export class ItemRoutingModule {
}

HTML:

<p>
  item works!
</p>

I was expecting to get the following for the url localhost:4200/core/item:

APP Works!
core module
item works

But, I am getting:

APP Works!
item works

So, item router is directly rendering in the app template instead of the core template.

Upvotes: 2

Views: 511

Answers (1)

Max Koretskyi
Max Koretskyi

Reputation: 105439

If you merge your routes, you get the following routing tree:

const routes = {
  path: 'core',
  children: [
    {
      path: 'item',
      children: [
        {
          path: '',
          component: ItemComponent
        }
      ]
    },
    {
      path: '',
      component: CoreComponent
    }
  ]
};

When you navigate to /core/item, the router tries to match each segment with a routing path. So it first matches core - no component to render. It checks its children. The first child has path item, and it matches the segment item, so it applies this branch. It never matches {path:'',component: CoreComponent} leaf. The router continues matching until the entire URL is consumed.

You'll have what you're expecting with the following configuration:

const routes = {
  path: 'core',
  children: [
    {
      path: '',
      component: CoreComponent,
      children: [
        {
          path: 'item',
          children: [
            {
              path: '',
              component: ItemComponent
            }
          ]
        }
      ]
    }
  ]
};

Upvotes: 2

Related Questions