Module With Providers - deependhamecha/angular GitHub Wiki
Dont know the exact purpose of ModuleWithProviders
interface but majorly people use it to make a singleton service instance across eager modules and lazy loaded modules.
Suppose, there is
shared/shared.module.ts
@NgModule({
providers: [CounterService]
})
export class SharedModule { }
shared/counter.service.ts
@Injectable()
export class CounterService {
counter = 0;
}
app.module.ts
@NgModule({
imports: [BrowserModule, SharedModule, routing],
declarations: [AppComponent, EagerComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
Now, suppose there is a lazy loaded module.
lazy.module.ts
const routes: Routes = [
{ path: '', component: LazyComponent }
];
export const routing: ModuleWithProviders = RouterModule.forChild(routes); // You dont need to re-export it
@NgModule({
imports: [routing],
declarations: [LazyComponent],
})
export class LazyModule {}
/* OR ELSE
Doesn't make a difference though, either you do NgModule export or JS module export.
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
declarations: [LazyComponent],
})
export class LazyModule {}
*/
Now,
lazy.component.ts
@Component({
selector: 'app-lazy',
template: `
<p>Lazy Component</p>
<button (click)="increaseCounter()">Increase Counter</button>
<p>Counter: {{ counterService.counter }}</p>
`
})
export class LazyComponent {
constructor(public counterService: CounterService) {}
increaseCounter() {
this.counterService.counter += 1;
}
}
This will create 2 separate instance when trying to access from a different lazy loaded module or eagerly loaded module.
To make it singleton, use following.
shared.module.ts
@NgModule({})
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [CounterService],
};
}
}
app.module.ts
@NgModule({
imports: [BrowserModule, SharedModule.forRoot(), routing],
declarations: [AppComponent, EagerComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
lazy.module.ts
@NgModule({
imports: [routing],
declarations: [LazyComponent],
})
export class LazyModule {}
Now, when you use it from any Lazy Loaded Module. It will use same instance created in SharedModule
.