6

Reading official documentation of Angular

When the Angular router lazy-loads a module, it creates a new injector. This injector is a child of the root application injector. The router adds all of the providers from the root injector to the child injector. When the router creates a component within the lazy-loaded context, Angular prefers service instances created from these providers to the service instances of the application root injector.

Based on this I created a small app that has one service which is provided in App's root component. This service has a property which is bound to both lazy loaded component and eagerly loaded component. What I am expecting is, eagerly loaded component should use the service instance from old injector. Hence any changes in service's property by eager loaded component should not be reflected in lazy loaded component. Lazy loaded component should use the new service instance from child injector. But this doesn't happen. Can someone explain?

Here is the link to stackblitz.

1 Answer 1

12
  • Is lazy loading creating new Injector in Angular?

Right.

For every lazy loaded module angular creates injector which is inherited from parent injector.

But it doesn't mean that this inherited injector will create new instance for each services provided in parent inject unless you provide this service in lazy loaded module. Otherwise Angular will traverse up to tree to find provided service and will find it on parent injector.

So simply add your service to LazyModule providers array and it will be registered in LazyModule injector and this way LazyComponent will get instance from lazy loaded injector.

@NgModule({
  imports: [
    CommonModule,
    LazyRoutingModule
  ],
  providers: [AppService],     <=================
  declarations: [LazyComponent]
})
export class LazyModule { }

I also suggest you reading this article

Update

From comment:

So shouldn't we have similar behaviour in case of lazy loading, as from doc. The router adds all of the providers from the root injector to the child injector.

I believe only the code.

When angular creates lazy loaded injector(NgModuleRef) it only passes reference to parent injector(NgModuleRef).

enter image description here

And when it resolves AppService dependency it first look at child injector and then at parent because there is no registered AppService in child injector

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

But if I copy the same providers to the child injector, then instances received from DI framework are different right. Following will result false. const parentInjector = Injector.create([{ provide: ServiceA, useClass: ServiceA, deps: [] }]); const childInjector = Injector.create([{ provide: ServiceA, useClass: ServiceA, deps: [] }], parentInjector); console.log(childInjector.get(ServiceA) === parentInjector.get(ServiceA)); So shouldn't we have similar behaviour in case of lazy loading, as from doc. The router adds all of the providers from the root injector to the child injector.
We don't copy providers to child injector we inherit. They still live in parent injector.
I got what you mean. Let me find the place where angular creates child injector
Thanks, It makes sense now after seeing the code, Angular team might rephrase that statement in documentation. Also where can I locate these core.umd.js and router.umd.js to see it for myself?
You can open chrome devtools than switch to Sources tab, press Ctrl+P and start typying core or router

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.