DEV Community

Cover image for Why EventEmitters instead of Subjects in Angular
Massimo Artizzu
Massimo Artizzu

Posted on

4 4

Why EventEmitters instead of Subjects in Angular

Recently I was thinking about how Angular uses the awesome library RxJS, and specifically when observable objects are created and expected.

One of them is the EventEmitter class that's used solely for emitting custom events in @Output-decorated properties, like this:

@Component({ ... })
class MyTab {
  @Output() selected = new EventEmitter<void>();
  ...
}
Enter fullscreen mode Exit fullscreen mode

But what are EventEmitters? Why are they used for @Output properties only? What do they add to the mix?

It turns out that the class EventEmitter, as of Angular 11.2.3, extends RxJS' Subject, adding just two things to the mix:

  • an emit method that internally just calls super.next;
  • an optional, less-known constructor argument isAsync (defaulting to false), that schedules the event emission on a subsequent task upon subscription (using the plain old setTimeout).

That's it. EventEmitters don't automatically complete when the view is destroyed (that would be great, IMO). They don't do anything special, but the async option could be useful somewhere else, right?

But digging a little deeper, it looks like the Angular team initially designed EventEmitter to be an extension of Subject out of... convenience? And had something else in mind that could probably not involve observables at all. That's why Ward Bell stated you shouldn't use EventEmitters for anything else than @Output properties, and none should pipe them or subscribe to them.

But... that comment is five years old. And nothing has changed since then. EventEmitter still extends Subject, and I know for a fact that there's code in production that explicitly subscribes to EventEmitters, or that uses simpler observables for @Output properties. And now the fact that EventEmitter extends Subject is also explictly mentioned in the official documentation.

I think the Angular team should set this in stone and call it a day. I see no reason to change the observable nature of Angular's custom events.

Maybe I'm missing something here, and anything can change in the future. For the time being, I'll still refrain from using EventEmitters for anything that they're not supposed to be used for, just in case. (Also because they don't actually add much. And the class name is pretty specific, and misleading if not used for... emitting events, duh.)

But coding @Output properties that are not EventEmitters... eh, that could actually be useful and simplify some code. With caveats.

AWS Security LIVE! Stream

Practical guidance for security practitioners

Don't miss AWS Security LIVE! Whether you're an AWS newbie or a seasoned pro, this show has something for everyone with actionable tips, expert advice, and security knowledge.

Learn More

Top comments (0)

AWS Security LIVE! Stream

Tackle challenges with the AWS security community

Join AWS Security LIVE! for an in-depth look at how to secure your AWS environment. Engage with security pros, participate in live discussions, and enhance your knowledge.

Learn More

πŸ‘‹ Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay