Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - multiple instance of service created

I have created AngularJS 2 service and use it in 2 differents components : App-Component & Sub-Component. Each one output property 'log' (a string) of my service.

StateService class :

@Injectable () class StateService {      public log : string;     static count : number = 0;      constructor () {         this.log = '';         StateService.count++;         this.writeToLog ('CREATED '+StateService.count+' at ' + new Date().toString());     }      public writeToLog (text : string) : void {         this.log += text + '\n';     } }   

Component :

@Component ({     selector : 'Sub-Component',     template : `<hr>             This is the Sub-Component !             <BR>             StateService Log :              <pre>{{ _stateService.log }}</pre>             <button (click)="WriteToLog ()">Write to log</button>             `,     providers : [StateService] })  export class SubComponent {     constructor (private _stateService : StateService) {     }      public WriteToLog () : void {         this._stateService.writeToLog ('From Sub-Component - This is '+new Date().toString());     } } 

Live example of code here

I except that service is created once and when each component call WriteToLog method, the output is the same in each component but it's not.

Example of output :

The App-Component can output this :

Instance 1 - Created at Thu Jan 21 2016 11:43:51

From App-Component - This is Thu Jan 21 2016 11:43:54

From App-Component - This is Thu Jan 21 2016 11:43:55

and the Sub-Component can output this :

Instance 2 - Created at Thu Jan 21 2016 11:43:51

From Sub-Component - This is Thu Jan 21 2016 11:43:57

From Sub-Component - This is Thu Jan 21 2016 11:43:58

So it appear that 2 instance of service is created (instance 1 + instance 2)

I only want one instance ;) and when I append string in log, this must appear in both component.

Thank you for your help

like image 945
Philippe sillon Avatar asked Jan 21 '16 16:01

Philippe sillon


People also ask

Does Angular create multiple instances of service?

Now it is a service that can be used between parent and child components. In this case, service is a non-singleton nature. It will create multiple instances of a service. Every time a new instance of provided service will be created when a component is used inside another component.

How many instances of service get created in Angular?

Angular DI maintains a single instance per provider. In your case if you have two constructor parameters with the same type, they resolve to the same instance.

Can we create multiple instances on one time?

If you start three Java applications at the same time, on the same computer, using the same concrete implementation, you'll get three Java virtual machine instances. Each Java application runs inside its own Java virtual machine.

How do you prevent to use a service as a singleton in Angular?

There are multiple ways to prevent this: Use the providedIn syntax instead of registering the service in the module. Separate your services into their own module. Define forRoot() and forChild() methods in the module.


1 Answers

update Angular >= 2.0.0-RC.6

Don't add the service to the providers of the component. Instead add it to

@NgModule({ providers: [...], ... 

(of a module that is not lazy loaded because lazy loaded modules introduce their own scope)

@Component ({     selector : 'Sub-Component',     template : `<hr>             This is the Sub-Component !             <BR>             StateService Log :              <pre>{{ _stateService.log }}</pre>             <button (click)="WriteToLog ()">Write to log</button>             `,     // providers : [StateService] <== remove }) 

Angular <=2.0.0-RC.5

If you add it on a component you get a new service instance for each component instance. Instead add it to

bootstrap(AppComponent, [StateService]); 

You can have more fine-grained control by adding it to a single component, then this component and all children get the same instance injected but otherwise the application works with the instance created by bootstrap(). This is the "hierarchical" in Angulars DI.

See also
- http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html
- http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

like image 58
Günter Zöchbauer Avatar answered Sep 22 '22 05:09

Günter Zöchbauer