Tom Balcaen

(This page is intentionally minimalistic. It's my desire to prioritise for the things that are necessary.)

Component communication through eventbus (mediator pattern)

When an application structure is rather complicated and components are depply nested. It can be tedious to solve communication between these components. (or services) Usually communication between components is provided by property bindings and event bindings a.k.a. @Input() and @Output(). For solutions that require communication between components that are deeply nested or have no parent-childe relations one of the options is an eventbus.

An eventbus is going to allow us to send data to components and act as some type of mediator. (mediator pattern) the component do not need to know about each other. We can assume that the pattern looks like the diagram below.

insert diagram

  1. First a component is going to subscribe to an event on the eventbus.
  2. Second another component is going to emit an event with the data that it wants to send. When the component fires the event. It does not know who's listening and does not care.
  3. The event data will be send to all components or services subscribed to the eventbus subscription.

How does this look in code?

I created a simple example application that will display a list of super heroes and their details. When a particular hero is selected, it will send its data to the eventbus to broadcast that dat to components who are listening to that subscription.

When we look at the folderstructure we ca nse that the application exist of a container component hero-container and two presentation components, hero-list and hero-details. In the core folder we can find the eventbus service which will be our communication mediator.

event-bus.service

The eventbus service has a subject that will send the data. When a component want to subscribe to a particular event, it will do that by calling the on function. That receives the type of event (In our case it is an Enum with only one event) and the action to call and take. With the pipe we are calling some rxjs functions to manipulate the incoming data into the subject. With filter we are filtering out the events that we actually want. With the map we map the value to the subscription and pass the value that was filtered.

The component that is going to fire the data is going to call the emit function. This will allow them to emit the event on the subscription. This will cal lthe next() operator on the subject and provide its data.

How to use the eventbus

Hero-list is a component that shows a list of heroes. When you click on a hero. The component wants to notify other components, for example our hero-details component.

In the code you can see that the first thing we need to do is inject the eventbus through dependency injection. After that we will send a new EmitEvent (see EmitEvent class) and call the emit function inside the eventbus service. The hero data and event will be provided.

In hero-container we will also inject the eventbus and call the on function. Telling it that we want to call the function provided on the heroClicked event. This function will pass the hero data to a local property hero.

This data will be provided to hero-details through a property binding and an Input.

Conclusion

With the eventbus it is possible to communication on any level of an application. It doesn't matter how deeply nested a component is. This method has some pros and cons.

pros

simple to use
loosely coupled
lightweight

cons

No way to know who triggered the event.
Loosely coupled, sometimes need more maintenance especially when a lot of event are triggered.