Inject the instance of a component in a service

Karbos 538 picture Karbos 538 · Dec 1, 2016 · Viewed 8.7k times · Source

For a any good reaon, I am trying to inject my component into a service, but I obtain a new instance of it. I reproduce my problem with this code :

This component will display the instance number in h1 :

@Component({
    selector: 'my-component',
    template: '<h1>Instance number {{count}}</h1>'
})
export class MyComponent {
    private static i = 0;               /* <-- counts the myComponent's instances here */
    private _count: number = i++;
    get count(): number {return this._count}
}

The Service will log the instance number in console:

@Injectable()
export class MyService {
    constructor(myComponent: MyComponent) {
        console.log("Instance number " + myComponent.count);
    }
}

The main component will inject the component in a view and the service :

@Component({
    selector: 'app-root',
    template: '<my-component></my-component>',
})
export class AppComponent {
    constructor(service: MyService) {
    }
}

I'm using angular-cli, my app.module.ts looks :

@NgModule({
  declarations: [
    AppComponent,
    MyComponent
  ],
  imports: [
    BrowserModule,
  ],
  providers: [MyComponent, MyService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Currently, my console displays Instance number 0 and my html display Instance number 1. How can I obtain the same instance ?

Thanks for reading me

Answer

G&#252;nter Z&#246;chbauer picture Günter Zöchbauer · Dec 1, 2016

This doesn't work. If your application has several instances of this component, which one should it inject.

What you can do is for example to inject the service to the component and make the component pass itself to the service

@Component({
    selector: 'my-component',
    template: '<h1>Instance number {{count}}</h1>'
})
export class MyComponent {

    constructor(service: MyService) {
      service.myComponent = this;
    }

    private static i = 0;
    private _count: number = i++;
    get count(): number {return this._count}
}

It's better to not pass components to services but instead use observables to notify components about events and let components do the rest.

For more details see https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service