๐ Event Emitters in Angular ๐
When you start learning Angular one of the first things you learn is how to communicate between child and parent components.
Data flows into your component via property bindings and flows out of your component through event bindings.
If you want your component to notify his parent about something you can use the Output
decorator with EventEmitter
to create a custom event.
We can use the Output
decorator to label our property add
as an event a component can fire to send data to its parent.
The parent can listen to an event like this:
Angular will subscribe to the add
event and call the addTodo()
method with the data when the component triggers the next()
method.
What is EventEmitter ๐
If you take a look at the source code, you are going to see something interesting.
Behind the scenes, Event Emitters are just Subjects.
The first thing you can learn from the source code is that you can pass a boolean to EventEmitter
that will determine whether to send events in a synchronous or asynchronous way. ( The default is synchronous )
๐ช You have the power of Rx ๐ช
Because EventEmitters
are Subjects
,we can use all the Rx goodness. For example, we want to emit an event only if we have a value.
Very very cool! ๐
Thatโs not all. We can also use any Subject
that we want. Letโs try to use BehaviorSubject
.
๐EventEmitters !== DOM events ๐ฒ
Unlike DOM events Angular custom events do not bubble. What it means if you defined something like this:
You can only listen to the TodoComponent
toggle
event at the parent level.
So this will work:
But this will not work:
๐ค The solutions โ
1. Keep passing the event up the tree
In this example itโs fine, but it can be frustrating if you will have nested components.
2. Use native DOM events
You can create native DOM events like this:
The custom event is dispatched by invoking the dispatchEvent()
method. We can pass data to our event with the detail
property.
Event bubbling will work here, but the problem with this approach is that we miss out on the opportunity to be able to execute also in none-DOM environments such as native mobile, native desktop, web worker or server side rendering.
3. Shared Service
We are using TodoService
as a message bus. You can learn more about this approach from the documentation.
๐ป Letโs be crazy ๐ค
Because EventEmitters
are observables, we can do some crazy things with them. I donโt know, letโs say you have a button component, and you need to know when the user is finished press all x buttons and then get the latest value from each.
If you want to know more about the code above, read my article Manage your Filters Like a Pro in Angular With combineLatest.
๐ In Case You Missed It
Here are a few of my open source projects:
- Akita: State Management Tailored-Made for JS Applications
- Spectator: A Powerful Tool to Simplify Your Angular Tests
- Transloco: The Internationalization library Angular
- Forms Manger: The Foundation for Proper Form Management in Angular
- Cashew: A flexible and straightforward library that caches HTTP requests
Follow me on Medium or Twitter to read more about Angular, Akita and JS!