0

I have an library with 2 components and 2 services A & B.

2 of the components are using my service A.. no problem there - I can see that A have been created once - I've wrote to the console in the ctor.

Service B needs service A for his doings, therefor it injects A. and now i see another creation of A (in the console)

service B is doing, The same way as the components are doing.

import  { A } from './A'
.
.
.
constructor(private myA: A) {...}

But this time it is creating my service A again. so i have 2 instance.

This is not good for me.. and also weird.. I'm relatively new in the new generation of angular - And all the time struggling with that on small things like this.. It is frustrating.

Anyone ?

UPDATE

I've realised that it happens in my clients app when they have lazy loading for sub module, and importing my module there..

For ex.

partials.modules.ts

@NgModule({ declarations: [..],exports: [...], imports: [ ..., MyModule ]});
export class PartialsModule {}

pages.module.ts -- lazy loaded by the routing

@NgModule({ declarations: [..],exports: [...], imports: [ ..., PartialsModule ]});
export class PagesModule {}

app.module.ts

@NgModule({ declarations: [..],exports: [...], imports: [ ..., PartialsModule ]});
export class AppModule {}

app module is creating an instance of MyMoudle->my service, and PagesModule as well. I guess it is because of the lazy modules which has their own injectors.

But how can i solve it ?

I've tried moving the import of my module to the app.module.ts with the forRoot static method as explained here. Now the components in the partialModule fail to find the components in MyModule (My library)

:(

Raziza O
  • 1,560
  • 1
  • 17
  • 37
  • Decorate service A with `@Injectable({ providedIn: 'root' })` – peinearydevelopment Feb 26 '19 at 13:21
  • All my services have this injected.. And the service is working well as long as we use it from other components.. It is just happening when i'm using it from another service. Then the other service creates it.. – Raziza O Feb 26 '19 at 13:39
  • Is it added in a providers list anywhere or is it just given the above decorator? – peinearydevelopment Feb 26 '19 at 13:41
  • I've posted it 5 days ago and let it rest.. now that i'm checking again with you it looked like it is creating once the service as I wanted and as expected.. Ahhh... this new angular! anyway, I guess i will delete this post soon after i verify that it is working for few days in a row :) – Raziza O Feb 26 '19 at 13:49
  • Good that i didn't delete the post.. Check updates – Raziza O Mar 03 '19 at 11:51

2 Answers2

0

The problem here is in wich level component are you providing the Service?

If you have the provider at level componet you will get an instance each time the component initialize.

Then I recomend you add this decorator to specify the root module as provider. @Injectable({ providedIn: 'root' })

Or specify directly in the module where you need it as: Example:

@NgModule({ declarations: [..],exports: [...], imports: [ ..., MyModule ], providers:[SERVICE_A]});
Abel Valdez
  • 2,368
  • 1
  • 16
  • 33
  • `@Injectable({ providedIn: 'root' })` is written in all my services. Didn't understand the second half of your answer.. Should I put my module import in the `app.module.ts`? should i use `forRoot()` way? – Raziza O Mar 03 '19 at 16:38
  • Let’s try the following priovide the service in the app module and remove the service decorator – Abel Valdez Mar 03 '19 at 16:40
  • When i'm importing `myModule` in the app - then the lazy modules does not recognising the components within this module – Raziza O Mar 03 '19 at 16:43
  • Try by doing this it will create like a single instance of the service for all the application: `@NgModule({ declarations: [..],exports: [...], imports: [ ..., PartialsModule ], providers:[serivice_A]}); export class AppModule {}` – Abel Valdez Mar 03 '19 at 16:50
  • The problem when i'm putting it only in the `appModule` is that the components in `partialsModule` does not recognise the components in `myModule`. – Raziza O Mar 04 '19 at 08:37
  • I mean the service, not your componente. Take a look the last comment in the part of providers there put the classname of your service that is not working and internally in the service remove the the decorador root. There’s any way you upload your code to help u ? Maybe github. Because it could be that you are using ngIf to show or hide the component you are creating another instance for the component and if the service is in the same level you are getting a new instance of the service too. That’s why im telling you can provide the service directly in the app module just the service no compo – Abel Valdez Mar 04 '19 at 14:31
  • I'm providing library -> module (with services and components) to an application used by my clients. When they import my module all of this happens. Unfortunately, cannot upload my or my clients code. But I've posted an answer that works for me. Check it out. And thanks for all your help – Raziza O Mar 05 '19 at 21:25
0

After a struggle of few days, I'm sharing the solution I've found

My services in my module had

// angular 6
@Injectable({
  providedIn: 'root'
})

Means that your injectable will be registered as a singleton in the application, and you don’t need to add it to the providers of the root module, for more info read here.

And now, The problem.. My Module had providers property in the decorator.

@NgModule({
  imports: [...],
  declarations: [...],
  exports: [...],
  providers: [MyService] // <<------- THIS LINE WAS THE PROBLEM - no need for providers in the module
})
export class MyModule { }

Simply removing the provides from the module solved my problem.

No need for forRoot method.

When my clients use my library and import my module it is calling the ctor of the module as many time as imported, but the Ctor of my services are called once, which mean all sharing the same instance..

Raziza O
  • 1,560
  • 1
  • 17
  • 37