简体   繁体   中英

What would cause an Angular2 service to create multiple instances?

I have created a service and provided it in 'root' in my project (using the standard shortcut). However, it appears to be creating multiple instances instead of using the same instance. I diagnosed this by setting an instance variable ID equal to a random value in the constructor and then printing this to console on method calls.

@Injectable({
    providedIn: 'root'
  })

console.log(`Hodor ${this.ID}`);

This is a problem since the additional instance doesn't seem to have access to the component that I've designated for output. When I trigger events through the component, the service handles them and places output in that component. However, when I trigger them through another component, they go to the second instance and do not produce output.

My app has multiple feature modules, which are imported to a core module and then to the app module (app-->core-->feature). I've tried providing the service in a separate module and importing it to app but this doesn't make any difference. Is there any way to keep the second instance from appearing? Shouldn't 'root' take care of this?

At this point I'm thinking of using the classic OOP strategy of setting a static variable for the service and then having the constructor either set that or return it if it's already defined. However that pattern is definitely not standard Angular.

OK, I have the answer and it's a good one. VSCode has a bug which causes it to intermittently add the .js extension to Typescript class imports. This often doesn't impact the functioning of the code since the .js classes do get created at runtime by the TS transpiler (even though we'd all prefer that it point to the original .ts files). However, this causes Angular to recognize the .js files as a different file and if that file includes a service causes it to create a new service instance, as happened here. It's something I'll definitely be on the lookout for in the future.

This is most likely caused by a different module declaring its own provider for the service - either by listing it in its providers , or by importing a module who does.

You can debug this by setting a break point in the service constructor, and checking the caller's variables to find out which injector creates the second instance (and for which token, in case that's relevant). This should lead you to the module that declares the additional provider.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM