I have a component called DesignerComponent and subcomponents that share a service called ProjectService and this service is declared in a module called DesignerModule as a provider because DesignerComponent and the subcomponents must share the ProjectService instance.
Everything works fine, but when I go to another page and come back to this page, the service still holds all the old data, in other words this service instance is never recreated. How can I force Angular to create a new service instance when leaving and coming back to a module or page but still be able to share one instance among the subcomponents?
app.module.ts
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
FormsModule,
RouterModule.forRoot([
{ path: '', loadChildren: () => import('./site/site.module').then(u => u.SiteModule) },
{ path: 'designer', loadChildren: () => import('./designer/designer.module').then(u => u.DesignerModule), canActivate: [AuthGuard] },
{ path: 'signin', loadChildren: () => import('./login/signin/signin.module').then(u => u.SigninModule) },
{ path: 'signup', loadChildren: () => import('./login/signup/signup.module').then(u => u.SignupModule) },
]),
BrowserAnimationsModule,
StoreModule.forRoot(reducers, {
metaReducers,
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true,
}
}),
],
providers: [
ScriptService,
ComponentLoadService,
MessagingService,
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
],
bootstrap: [AppComponent],
})
export class AppModule { }
designer.module.ts
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{ path: ':id', component: DesignerComponent }
]),
AngularSplitModule.forRoot(),
...
],
declarations: [
DesignerComponent,
DesignerMenuComponent,
...
]
providers: [
ProjectService,
...
]
})
export class DesignerModule { }
project.service.ts
@Injectable()
export class ProjectService{
private historyModule: ProjectUndoRedo[] = []; // This value still hold old data after going to another page and coming back. I want this service to be reinitialized
}
designer.component.ts
export class DesignerComponent{
constructor(public projectService: ProjectService) {
// When this constructor is called, projectSerivce instance is the old instance.
}
}
designer-menu.component.ts
export class DesignerMenuComponent{
constructor(public projectService: ProjectService) {
// When this constructor is called, projectSerivce instance is the old instance.
}
}
Any service added to an NgModule is registered with the root injector (or the lazy injector for lazy loaded routed modules). Hence, the service scope is application-wide, and retains its values.
If you want to reduce the scope, then register the service with the component instead:
@NgComponent({
selector: 'app-designer',
providers: [
ProjectService
]
})
export class DesignerComponent {
}
This will register the service with the component injector (which is hierarchical) and its scope is limited to the lifetime of the component it was registered with.
When there are route changes, and the Designer component is replaced with another component, it will re-create and re-initialize the component (and any providers it is registered with).
Note: Since the lifetime of the service is closely tied to the lifetime of the component, you can also perform initialization routines for your service in ngOnInit and cleanup routines in ngOnDestroy of DesignerComponent, if needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With