Lazy loading and providers strategy
Asked Answered
W

2

7

Right now, using Angular v5, while using lazy loading, I load all my providers in app.module.ts which I guess isn't maybe the best strategy because this won't speed up my app boot time, specially because I've got something like 50 custom providers (don't judge me ;) ).

Therefore I'm asking my self if I should really load all of them for my all app or if I should load them only where I only use them?

I'm guessing it would be better to load providers only where I really use them.

But in such a case, it's for me then not clear at all how to solve following construct:

Let say I've got three pages (A,B and C) with their own modules and three providers (1,2 and 3).

A use 1
B use 1, 2, 3
C use 1, 2
  • I guess, since 1 is use across all the app, I would have to declare it in app.module.ts

  • Since 3 is only use in page B, I guess I would have to only declare it in B.module.ts

  • But what about 2? How could I declare it in both B.module.ts and C.module.ts with the goal to share the same provider "memory" (if the provider contains a value, both B and C should see the same object), respectively how I would code that? Simply by injecting the provider "as usual" and angular do the rest?

Thx in advance for any help, would really be appreciated

UPDATE

Not sure if I understand correctly the angular documentation but that's the goal, the providers should be loaded for the all app wide right?

See

https://angular.io/guide/ngmodule-faq#q-component-scoped-providers

UPDATE 2018

The injection strategy has evolved with the introduction of Angular v6. According the documentation it's possible with providedIn to specify in which module a service should be use. See https://angular.io/guide/dependency-injection

Wriest answered 12/10, 2017 at 11:33 Comment(0)
C
0

The answer is you should add your provider in app.module.ts because it is a singleton service. Here is from angular dependency injection doc:

Dependencies are singletons within the scope of an injector

It means when you declare your provider in app.module.ts it will be singleton in whole app and every module injected it will share the same instance of it.
When you declare your provider in separate modules i.e B.module.ts and C.module.ts, your B page will use an instance of provider and C page will use another instance of provider. And it is not the purpose of provider.

Cianca answered 13/10, 2017 at 2:37 Comment(4)
Yes I think you are right, may do some more testing locally before closing this question. ThxWriest
@PeterParker: Did you test it?Cianca
sorry I'm running behind time, didn't had and most probably won't have time to test this week. About "it's not the purpose of provider" I would no say yes and no. Yes if you want singleton, you have to declare them in app.module but it seems that angular also tells that it's ok to limit to the scope of a component to declare a provider in a module, see angular.io/guide/…Wriest
I did mark this answer as the valid one. If I understand correctly a. You use stateless providers, then yes you might be able to declare them in separate modules because if you do so, each modules gonna use is own provider (“no memory share between mutliple instance of the same provider”) b. Your providers aren’t stateless, for example you use them to keep values in memory, then they have to be only declared once for the all app respectively in app.module.tsWriest
P
1

you should create a shared module that intenciate your provider 2 and that the B and C module inculdes in their dependencies.

edit: you do not need to export providers.

Pleat answered 12/10, 2017 at 11:36 Comment(5)
Interesting, that would be a shared module without any declarations right? Something like @NgModule({providers: [2], exports: [2]})Wriest
it could work, it's howi work with modules that i need in more than one other module.Pleat
Doesn't work, also I just went thru again thru the documentation and I think now that it might be by design not possible and not recommendedWriest
It doesn't really work in lazy loading context, because each page has their own module. A shared module would work if lazy loading is not implemented.Tercel
Backing the comments above from OP and @Tercel , I just tried this and when loading the lazy-loaded pages, I get one call to the provider's constructor per each page, creating 2 instances.Renowned
C
0

The answer is you should add your provider in app.module.ts because it is a singleton service. Here is from angular dependency injection doc:

Dependencies are singletons within the scope of an injector

It means when you declare your provider in app.module.ts it will be singleton in whole app and every module injected it will share the same instance of it.
When you declare your provider in separate modules i.e B.module.ts and C.module.ts, your B page will use an instance of provider and C page will use another instance of provider. And it is not the purpose of provider.

Cianca answered 13/10, 2017 at 2:37 Comment(4)
Yes I think you are right, may do some more testing locally before closing this question. ThxWriest
@PeterParker: Did you test it?Cianca
sorry I'm running behind time, didn't had and most probably won't have time to test this week. About "it's not the purpose of provider" I would no say yes and no. Yes if you want singleton, you have to declare them in app.module but it seems that angular also tells that it's ok to limit to the scope of a component to declare a provider in a module, see angular.io/guide/…Wriest
I did mark this answer as the valid one. If I understand correctly a. You use stateless providers, then yes you might be able to declare them in separate modules because if you do so, each modules gonna use is own provider (“no memory share between mutliple instance of the same provider”) b. Your providers aren’t stateless, for example you use them to keep values in memory, then they have to be only declared once for the all app respectively in app.module.tsWriest

© 2022 - 2024 — McMap. All rights reserved.