I\'ve read questions like Access EventEmitter Service inside of CustomHttp where the user uses EventEmitter in his service, but he was suggested in this comment not to use
There is no: nono and no: yesyes. The truth is in the middle And no reasons to be scared because of the next version of Angular.
From a logical point of view, if You have a Component and You want to inform other components that something happens, an event should be fired and this can be done in whatever way You (developer) think it should be done. I don't see the reason why to not use it and i don't see the reason why to use it at all costs. Also the EventEmitter name suggests to me an event happening. I usually use it for important events happening in the Component. I create the Service but create the Service file inside the Component Folder. So my Service file becomes a sort of Event Manager or an Event Interface, so I can figure out at glance to which event I can subscribe on the current component.
I know..Maybe I'm a bit an old fashioned developer. But this is not a part of Event Driven development pattern, this is part of the software architecture decisions of Your particular project.
Some other guys may think that use Observables directly is cool. In that case go ahead with Observables directly. You're not a serial killer doing this. Unless you're a psychopath developer, So far the Program works, do it.
TL;DR:
No, don't subscribe manually to them, don't use them in services. Use them as is shown in the documentation only to emit events in components. Don't defeat angular's abstraction.
Answer:
EventEmitter is an angular2 abstraction and its only purpose is to emit events in components. Quoting a comment from Rob Wormald
[...] EventEmitter is really an Angular abstraction, and should be used pretty much only for emitting custom Events in components. Otherwise, just use Rx as if it was any other library.
This is stated really clear in EventEmitter's documentation.
Use by directives and components to emit custom Events.
Angular2 will never guarantee us that EventEmitter will continue being an Observable. So that means refactoring our code if it changes. The only API we must access is its emit()
method. We should never subscribe manually to an EventEmitter.
All the stated above is more clear in this Ward Bell's comment (recommended to read the article, and the answer to that comment). Quoting for reference
Do NOT count on EventEmitter continuing to be an Observable!
Do NOT count on those Observable operators being there in the future!
These will be deprecated soon and probably removed before release.
Use EventEmitter only for event binding between a child and parent component. Do not subscribe to it. Do not call any of those methods. Only call
eve.emit()
His comment is in line with Rob's comment long time ago.
Simply use it to emit events from your component. Take a look a the following example.
@Component({
selector : 'child',
template : `
<button (click)="sendNotification()">Notify my parent!</button>
`
})
class Child {
@Output() notifyParent: EventEmitter<any> = new EventEmitter();
sendNotification() {
this.notifyParent.emit('Some value to send to the parent');
}
}
@Component({
selector : 'parent',
template : `
<child (notifyParent)="getNotification($event)"></child>
`
})
class Parent {
getNotification(evt) {
// Do something with the notification (evt) sent by the child!
}
}
class MyService {
@Output() myServiceEvent : EventEmitter<any> = new EventEmitter();
}
Stop right there... you're already wrong...
Hopefully these two simple examples will clarify EventEmitter's proper usage.
When you want to have cross component interaction, then you need to know what are @Input , @Output , EventEmitter and Subjects.
If the relation between components is parent- child or vice versa we use @input & @output with event emitter..
@output emits an event and you need to emit using event emitter.
If it's not parent child relationship.. then you have to use subjects or through a common service.
EventEmitter
is a public, documented type in the final Angular Core API. Whether or not it is based on Observable
is irrelevant; if its documented emit
and subscribe
methods suit what you need, then go ahead and use it.
As also stated in the docs:
Uses Rx.Observable but provides an adapter to make it work as specified here: https://github.com/jhusain/observable-spec
Once a reference implementation of the spec is available, switch to it.
So they wanted an Observable
like object that behaved in a certain way, they implemented it, and made it public. If it were merely an internal Angular abstraction that shouldn't be used, they wouldn't have made it public.
There are plenty of times when it's useful to have an emitter which sends events of a specific type. If that's your use case, go for it. If/when a reference implementation of the spec they link to is available, it should be a drop-in replacement, just as with any other polyfill.
Just be sure that the generator you pass to the subscribe()
function follows the linked spec. The returned object is guaranteed to have an unsubscribe
method which should be called to free any references to the generator (this is currently an RxJs Subscription object but that is indeed an implementation detail which should not be depended on).
export class MyServiceEvent {
message: string;
eventId: number;
}
export class MyService {
public onChange: EventEmitter<MyServiceEvent> = new EventEmitter<MyServiceEvent>();
public doSomething(message: string) {
// do something, then...
this.onChange.emit({message: message, eventId: 42});
}
}
export class MyConsumer {
private _serviceSubscription;
constructor(private service: MyService) {
this._serviceSubscription = this.service.onChange.subscribe({
next: (event: MyServiceEvent) => {
console.log(`Received message #${event.eventId}: ${event.message}`);
}
})
}
public consume() {
// do some stuff, then later...
this.cleanup();
}
private cleanup() {
this._serviceSubscription.unsubscribe();
}
}
All of the strongly-worded doom and gloom predictions seem to stem from a single Stack Overflow comment from a single developer on a pre-release version of Angular 2.