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
Angular will subscribe to the add event and call the addTodo() method with the data when the component triggers the next() method.
subscribe() is an EventEmitter method that registers handlers for events emitted by this instance. subscribe() have three optional parameters which can be used to pass values, errors, or completion notification in EventEmitter .
Conclusion. Use Eventemitter when transferring data from child component to parent component. Use Subject to transfer data from one component to another component.
In @angular/core, we have @Output and EventEmitter which allow us to emit event from one component to another. Let us see how to do this. Say there is a button inside the child component and we create a variable index which is passed as the parameter of the event.
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);
}
}
Plunker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With