How to subscribe to an event in a service in Angular2?

I know how to raise an event using EventEmitter. I can also attach a method to call if I have such a component:

<component-with-event (myevent)="mymethod($event)" /> 

When I have such a component, everything works fine. I have moved some logic to the service, and I need to raise the event from within the Service. I have done this:

 export class MyService { myevent: EventEmitter = new EventEmitter(); someMethodThatWillRaiseEvent() { this.myevent.next({data: 'fun'}); } } 

I have a component that should update some value based on this event, but I cannot get it to work. I tried this:

 //Annotations... export class MyComponent { constructor(myService: MyService) { //myService is injected properly and i already use methods/shared data on this. myService.myevent.on(... // 'on' is not a method <-- not working myService.myevent.subscribe(.. // subscribe is not a method <-- not working } } 

How to get MyComponent to subscribe to an event when the service that boosts it is not a component?

I'm on 2.0.0-alpha.28

EDIT: modified my “working example” to actually work, so focus can be placed on the non-working part;)

Code example: http://plnkr.co/edit/m1x62WoCHpKtx0uLNsIv

+54
javascript angular
Jun 30 '15 at 6:51
source share
2 answers

Update . I found a better / correct way to solve this problem using BehaviorSubject or Observable and not EventEmitter. See this answer: stack overflow

In addition, Angular docs now have an example cookbook that uses a theme .




Original / obsolete / incorrect answer: again, do not use EventEmitter in the service . This is an anti-pattern.

Using beta.1 ... NavService contains an EventEmiter. The Navigation component dispatches events through the service, and the ObservingComponent component subscribes to events.

nav.service.ts

 import {EventEmitter} from 'angular2/core'; export class NavService { navchange: EventEmitter<number> = new EventEmitter(); constructor() {} emitNavChangeEvent(number) { this.navchange.emit(number); } getNavChangeEmitter() { return this.navchange; } } 

components.ts

 import {Component} from 'angular2/core'; import {NavService} from '../services/NavService'; @Component({ selector: 'obs-comp', template: `obs component, item: {{item}}` }) export class ObservingComponent { item: number = 0; subscription: any; constructor(private navService:NavService) {} ngOnInit() { this.subscription = this.navService.getNavChangeEmitter() .subscribe(item => this.selectedNavItem(item)); } selectedNavItem(item: number) { this.item = item; } ngOnDestroy() { this.subscription.unsubscribe(); } } @Component({ selector: 'my-nav', template:` <div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div> <div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div> `, }) export class Navigation { item = 1; constructor(private navService:NavService) {} selectedNavItem(item: number) { console.log('selected nav item ' + item); this.navService.emitNavChangeEvent(item); } } 

Plunker

+71
Dec 21 '15 at 19:24
source share

Using alpha 28, I programmatically subscribed to event emitters using the eventEmitter.toRx().subscribe(..) method. Since this is not intuitive, perhaps this may change in a future version.

+3
Jul 06 '15 at 8:54
source share



All Articles