Reputation: 15196
I know how to raise an event with the EventEmitter. I can also attach a method to be called if I have a component like this:
<component-with-event (myevent)="mymethod($event)" />
When I have a component like this, everything works great. I moved some logic into a service and I need to raise an event from inside the Service. What I did was this:
export class MyService {
myevent: EventEmitter = new EventEmitter();
someMethodThatWillRaiseEvent() {
this.myevent.next({data: 'fun'});
}
}
I have a component that needs to update some value based on this event but i can't seem to make it work. What I tried was 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 do i make MyComponent subscribe to the event when the service that raises it is not a component?
I'm on On 2.0.0-alpha.28
EDIT: Modified my "working example" to actually work, so focus can be put on the not-working part ;)
Example code: http://plnkr.co/edit/m1x62WoCHpKtx0uLNsIv
Upvotes: 132
Views: 227304
Reputation: 153
Sometime quick fix of library cause that added event import like
import { EventEmitter } from 'events';
You must change it with core libray using subscribe
import { EventEmitter } from '@angular/core';
Upvotes: 0
Reputation: 364697
Update: I have found a better/proper way to solve this problem using a BehaviorSubject or an Observable rather than an EventEmitter. Please see this answer: https://stackoverflow.com/a/35568924/215945
Also, the Angular docs now have a cookbook example that uses a Subject.
Original/outdated/wrong answer: again, don't use an EventEmitter in a service. That is an anti-pattern.
Using beta.1... NavService contains the EventEmiter. Component Navigation emits events via the service, and component ObservingComponent subscribes to the 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);
}
}
Upvotes: 164
Reputation: 79
Using alpha 28, I accomplished programmatically subscribing to event emitters by way of the eventEmitter.toRx().subscribe(..)
method. As it is not intuitive, it may perhaps change in a future release.
Upvotes: 7