7
votes

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)
],
3
This answer may help you. If you see my profile, you will see a large scale application on how routing modules work. Hope this helps. stackoverflow.com/questions/49621578/…harold_mean2
@harold_mean2 thanks for the reply. I've checked the answer you mentioned but couldn't solve the issue based on it. The problem seems to be related with nesting lazy loaded paths.GCSDC
Each module you import has its own <router-outlet></router-outlet>. You can extend these modules like a tree component. My answer works because that is how I implement my app. youtube.com/watch?v=z5lHNx640wY I hope you find your answer and good luck with your app.harold_mean2
Thanks again, @harold_mean2 but this didn't work for me. Anyway, I finally got it working by using children on core-routing.module.ts and including the lazy loaded routes inside it. Will post this as answer.GCSDC

3 Answers

7
votes

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.

1
votes

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

0
votes

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:

https://blog.angularindepth.com/the-three-pillars-of-angular-routing-angular-router-series-introduction-fb34e4e8758e

The complexity resolving my bug was from 2 issues:

  1. I had a reference to my lazy loaded module in another part of my application. The lowest level lazy-load module had a route '' redirect. Because it was already loaded, the redirect was being caught at the root level of the route tree, setting the contents of the top most router outlet (in your example the outlet in app.component.html) instead of the nested outlet (your core.component.html). It looked like it was working but having an issue targeting the correct outlet, but nope, that wasn't it!
  2. The second was that my lowest level lazy-loaded router module didn't use the fully qualified route then when I resolved point #1, I was getting an empty nested outlet but no error letting me know that no route existed.

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!