I have an app with 2 main modules, web and admin.
Admin declares
providers: [
{
provide: DISPLAY_LIFE_TOKEN,
useValue: 6000,
},
],
and web declares the same token with useValue: 10000
.
Both modules contain a route and components that use a service with providedIn: 'root',
that imports the token DISPLAY_LIFE_TOKEN
.
Yet in the service, the config value is always 10000
even when calls come from the admin module.
See demo.
Did i misunderstand something about injectionTokens and providers, or is there another preferred way to set a module wide config?
CodePudding user response:
So unless the module is a lazy loaded module, the providers are not created as separate instances, that is the issue, I guess the latest value of DISPLAY_LIFE_TOKEN
overrides the previous one.
One fix will be to use the providers array inside the root component of the module, this will ensure a separate instance is created for the provider DISPLAY_LIFE_TOKEN
. Also messageService
needs to have two separate instances! so remove the providedIn: 'root'
@Component({
selector: 'app-admin-main',
template: `admin: {{value}}`,
providers: [
MessageService,
{
provide: DISPLAY_LIFE_TOKEN,
useValue: 6000,
useExisting: true,
},
],
})
export class AdminMainComponent implements OnInit {
The second fix will be to simply convert them to lazy loaded modules instead.
CodePudding user response:
Services are singleton in Angular.
The only way around this is lazy loading. This ensures a separate instance is created for services provided in the lazy module.
Remove providedIn: 'root',
from the service.
Add the service to both module providers
array.
providers: [
MessageService,
{
provide: DISPLAY_LIFE_TOKEN,
useValue: 6000,
},
],
And update the router module to use lazy loading:
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
},
{
path: 'web',
loadChildren: () => import('./web/web.module').then(m => m.WebModule),
}]
(since this moves the path from admin module to app module, do not forget to also update the route in the admin module).