Understanding component events that bubble up from Lightning Components feels like it should be easy, but the naming of event classes threw me for a loop until I talked to a colleague about it. While the documentation is extensive, there are some nuances to how you implement your events. Hopefully this spares you the pain!
(p.s. this is not a discussion about Lightning Application events. Those are similar but are broadcast instead through a pub-sub.)
The Lightning Event class
Events all start with creating a Lightning Event (in the Developer Console: New > Lightning Event; in SFDX: sfdx force:lightning:event:create). To get it to bubble right you want to set type=“COMPONENT”. And then you add the fields you want to pass along as payload.
When you go to fire the event you will:
If you attempt to set the name of a parameter that is not defined in the event class it will not fail, but it won’t be set either. 😳
👉 (This is important if you refactor and then end up wondering why suddenly you are getting missing values when you thought for sure you were setting the payload correctly.)
Confused? Consider this:
If you want to catch a “click” event at the outer DIV you can set up a handler:
document.getElementById(‘iCatch’).addEventListener(‘click’, yourHandlerHere );
The click event bubbles up from the BUTTON to the P to the DIV.
Lightning events work on component hierarchy instead. Consider these two components:
The ParentComponent will emit a P then its child component then a final P:
As you can see there is no wrapping element to add a listener to. 🙀 But not to worry! If you register the name of your events and then set up handlers it will work as you expect. The trick is: name your events carefully.
Firing the event 🎈
Firing the event is easy. First register that you are about to throw an event in your component:
<aura:registerEvent name=“imBubblingUp" type=“c:MyBubbleEvent” />
Then in your controller/helper fire the event:
Catching the event 🕸
When you catch the event, you must handle the same name and same type:
<aura:handler name=“imBubblingUp” event=“c:MyBubbleEvent” action=“c.handleIt” />
In the controller/helper then you can pull out any payload parameters like a message:
var theMessage = event.getParam(‘message’);
Mismatched event names 🔀
This was one source of my own errors: you might think that the name of the event being fired was just a local name to that component, and the handler name is the name of the handler, but not so. The names must match — the event classes don’t. Huh?
The event name you register is the one that gets handled later. You can have multiple handlers for the same event too. Consider an event class named c.BubblingEvent that has multiple fields in its payload:
It gets registered as “theEvent” and fired. In its parent component you could process the same event three ways:
Yup. The parent component is listening for “theEvent” events and will use the “c:BubblingEvent” class shape to determine which getters you have access to. And, yes, all 3 handlers will get called. If you know the shape of the event, instead of using “c:BubblingEvent”, you could have defined 3 event classes that only expose a subset of BubblingEvent like just the userId or just the newCookie.
Just because you can … 😈
… doesn’t mean you should use different classes. I find it confusing if the names of the events plus their classes are registered one way and the handlers use the same event names but entirely different classes. You would be breaking the data contract. Keep It Simple. 🙂
So in summary:
- be careful constructing the payloads in your Lightning component events
- the child component registers the name of the event it wants to bubble and uses an event class to define the shape of the setters
- the parent component handles the same-named events and should use the same event classes