Reputation: 3540
I have an app on which I need only the sign in functionality to be available at startup, and all remaining code should be lazy loaded after user authenticates.
I've created a core.module with a core-routing.module and a core.component to handle this, but the child components (for example DashboardComponent) are being rendered inside router-outlet element on app.component.html and not at core.component.html and so the header is not being displayed.
I've already searched and a lot, but couldn't find how to have this working.
app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'signin', pathMatch: 'full' },
{ path: 'signin', component: SigninComponent },
{ path: 'app', loadChildren: './core/core.module#CoreModule', canLoad: [AuthGuard] },
{ path: '**', redirectTo: 'signin' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
app.component.html
<router-outlet></router-outlet>
core-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule', canLoad: [AuthGuard] },
{ path: '**', redirectTo: 'dashboard' }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CoreRoutingModule { }
core.component.html
<div id="header">
<app-header></app-header>
</div>
<main id="content">
<router-outlet></router-outlet>
</main>
dashboard-routing.module.ts
const dashboardRoutes: Routes = [
{ path: '', component: DashboardComponent, pathMatch: 'full' }
];
@NgModule({
imports: [
CommonModule,
MaterialModule,
SharedModule,
RouterModule.forChild(dashboardRoutes)
],
Upvotes: 9
Views: 12614
Reputation: 3540
After trying it on many different ways, what worked for me was changing core-routing.module.ts to have a single route and including the lazy loaded modules as children inside it:
const routes: Routes = [
{
path: '',
component: CoreComponent,
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', loadChildren: '../dashboard/dashboard.module#DashboardModule', canLoad: [AuthGuard] },
{ path: 'customers', loadChildren: '../customers/customers.module#CustomersModule', canLoad: [AuthGuard] },
{ path: 'history', loadChildren: '../history/history.module#HistoryModule', canLoad: [AuthGuard] },
{ path: 'processing', loadChildren: '../processing/processing.module#ProcessingModule', canLoad: [AuthGuard] },
{ path: '**', redirectTo: 'dashboard' }
]
}
];
Hope this may help someone trying to implement the same functionality.
Upvotes: 11
Reputation: 284
Well, I'm late to the party but just spent the past 5 days solid with the same problem. Posting here in case it helps.
Preamble, don't confuse named outlets per @Asanka response with nested outlets. My first readings through stack overflow I didn't realise the difference so wrongly tried to name outlets and understand how to route to them.
I found the answer by trawling through this excellent article (I'm not the author or affiliated with them):
https://medium.com/@shairez/angular-routing-a-better-pattern-for-large-scale-apps-f2890c952a18
Of particular interest is the linked Stackblitz project (see choose-address-routing.module.ts
line #9 that shows the second layer lazy loaded module route requires a fully qualified route).
I also took the day to read every line of this article (whole thread) to clarify my understanding:
The complexity resolving my bug was from 2 issues:
As per my solution your dashboard-routing.module.ts would look like:
const dashboardRoutes: Routes = [
{ path: '', , pathMatch: 'full', redirectTo: 'dashboard/child-view' },
{ path: 'dashboard/child-view', component: DashboardComponent, pathMatch: 'full' }
];
See that 'dashboard/child-view
' above! That's what I'm meaning by the fully qualified route to the second level router outlet (populated by the second level lazy loaded module).
I want my 5 days back! I'll accept Shiraz. Keen to hear if this helps you!
Upvotes: 0
Reputation: 1648
This is because of you have used 2 router outlets. so you have to name the routers to render component to correct one
<router-outlet name="secondRouterOutlet"></router-outlet>
{path: '/examplePath', component: secondComponentComponent, outlet: 'secondRouterOutlet'}
this stackoverflow answer might be helped
Upvotes: 1