Working with Angular15.
Create a lazy loading modules
app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', patchMatch: 'full' },
{ path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule) },
{ path: 'module1', loadChildren: () => import('./module1/module1.module').then(m => m.FirstModule) },
{ path: 'module2', loadChildren: () => import('./module2/module2.module').then(m => m.SecondModule) },
{ path: 'module3', loadChildren: () => import('./module3/module3.module').then(m => m.ThirdModule) },
{ path: 'module4', loadChildren: () => import('./module4/module4.module').then(m => m.FourthModule) },
];
@NgModule({
imports: [RouterModule.forChild(routes, {useHash:true})]
exports: [RouterModule]
})
export class AppRoutingModule {}
dashboard.module.ts -- Having components dependency with FirstModule, SecondModule, ThirdModule and FourthModule
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent},
];
@NgModule({
declarations: [DashboardComponent, DashboardDetailsComponent]
imports: [RouterModule.forChild(routes), FirstModule, SecondModule, ThirdModule, FourthModule]
exports: [RouterModule],
bootstrap: [DashboardComponent]
})
export class DashboardModule {}
module1.module.ts -- Having components dependency with SecondModule and ThirdModule
const routes: Routes = [
{ path: 'module1', component: Module1Component},
{ path: 'module1/details', component: Module1DetailsComponent},
];
@NgModule({
declarations: [Module1Component, Module1DetailsComponent]
imports: [RouterModule.forChild(routes), SecondModule, ThirdModule]
exports: [RouterModule],
bootstrap: [Module1Component]
})
export class FirstModule {}
module2.module.ts -- Having components dependency with ThirdModule
const routes: Routes = [
{ path: 'module2', component: Module2Component},
{ path: 'module2/details', component: Module2DetailsComponent},
];
@NgModule({
declarations: [Module2Component, Module2DetailsComponent]
imports: [RouterModule.forChild(routes), ThirdModule]
exports: [RouterModule],
bootstrap: [Module2Component]
})
export class SecondModule {}
With the above code getting error Error: NG04007: The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector. Lazy load modules hould use RouterModule.forChild instead
Its working fine only if DashboardModule is explicitly imported in AppRoutingModule
Below is a comprehensive example of using lazy-loading
, sharing-components between modules
, But first lets look at what went wrong!
The forRoot
should be used for the root level module ( here AppModule
) for all the lazy loaded routes we need forChild
, in your example for the app.routing.ts
you are using forChild
, so I guess thats where it went wrong!
You only need to export the essential components that need to be shared to other components, so there is no need to export RouterModule
, this can be done only if you are defining a separate file for routes module1.routing.ts
there is no need to export it!
Now lets focus on sharing components/directives.
If you are going to use something that is shared by all the modules, its better you create a module called SharedModule
this will contain the common items for all modules, eg CommonModule
is definetely required by all the modules, you can also share components. The important part is that, the component/directive needs to be in the declarations array of only one module and should be present in the exports array also for other modules to use it!
If you are sharing components/directives between only few modules, you can declare the component only on the original module but you need to add it to the exports array for it to be accessible by other modules, in the below example provided I am exporting module1Component
from module1
and using it in the dashboardModule
app routing ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{
path: 'dashboard',
loadChildren: () =>
import('./dashboard/dashboard.module').then((m) => m.DashboardModule),
},
{
path: 'module1',
loadChildren: () =>
import('./module1/module1.module').then((m) => m.FirstModule),
},
{
path: 'module2',
loadChildren: () =>
import('./module2/module2.module').then((m) => m.SecondModule),
},
{
path: 'module3',
loadChildren: () =>
import('./module3/module3.module').then((m) => m.ThirdModule),
},
{
path: 'module4',
loadChildren: () =>
import('./module4/module4.module').then((m) => m.FourthModule),
},
];
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})
export class AppRoutingModule {}
module 1 routing ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Module1Component } from './module1/module1.component';
import { Module1DetailsComponent } from './module1-details/module1-details.component';
const routes: Routes = [
{ path: '', redirectTo: 'module1', pathMatch: 'full' },
{ path: 'module1', component: Module1Component },
{ path: 'module1/details', component: Module1DetailsComponent },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class Module1RoutingModule {}
module 1 ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Module1RoutingModule } from './module1-routing.module';
import { Module1Component } from './module1/module1.component';
import { Module1DetailsComponent } from './module1-details/module1-details.component';
import { SecondModule } from '../module2/module2.module';
import { ThirdModule } from '../module3/module3.module';
import { SharedModule } from '../shared/shared.module';
@NgModule({
declarations: [Module1Component, Module1DetailsComponent],
imports: [
CommonModule,
Module1RoutingModule,
SecondModule,
ThirdModule,
SharedModule,
],
exports: [Module1Component], // <- exporting for dashboard to use
})
export class FirstModule {}
dashboard module using component of module 1
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DashboardDetailsComponent } from './dashboard-details/dashboard-details.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { RouterModule, Routes } from '@angular/router';
import { FirstModule } from '../module1/module1.module';
import { SecondModule } from '../module2/module2.module';
import { ThirdModule } from '../module3/module3.module';
import { FourthModule } from '../module4/module4.module';
import { SharedModule } from '../shared/shared.module';
import { Module1Component } from '../module1/module1/module1.component';
const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'from-module1', component: Module1Component }, // using module 1 file
];
@NgModule({
declarations: [DashboardComponent, DashboardDetailsComponent],
imports: [
RouterModule.forChild(routes),
FirstModule,
SecondModule,
ThirdModule,
FourthModule,
SharedModule,
],
})
export class DashboardModule {}
shared module, stores components/etc which is shared by all!
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [CommonModule],
exports: [CommonModule],
})
export class SharedModule {}
Stackblitz Demo
-> cd test
-> npm i
-> npm run start