This series introduces you to the Lightning Component Framework through a free online course by Salesforce University combined with a six part blog series written by Don Robins, a Salesforce MVP, Certified Advanced Developer and Certified Salesforce Instructor. Each post provides deeper insight and additional perspective around topics covered by each course module.
If you read our last post (the fourth in this series) and watched Module 4: Using Nested Components of our online course Creating Lightning Components, you learned a bit about nesting components in other components, and some of the benefits of a component-based architecture.
One of the primary benefits of using this architectural approach is that an application’s modules are loosely coupled. This simply means that there are minimal dependencies between the modules, which allows for a “plug-and-play” development approach. In the Lightning Framework, components can be easily added, removed or swapped without the risk of breaking the application. They can be built by different teams, or even purchased commercially through the AppExchange for integration in a custom application.
An event driven programming model is the key characteristic of such an architecture that allows independent components to seamlessly function together as a cohesive application. This is what we’ll focus on in Module 5: Raising and Handling Events: Part 1, and Module 6: Raising and Handling Events: Part 2.
Event Driven Programming
Developers who have used frameworks written in languages such as .NET, Java, and JavaScript, are likely familiar with concepts around event driven programming. An event driven programming model is required in applications heavily dependent upon a graphical user interface, such as those found in browser-based, mobile web or native mobile apps. Such apps focus heavily on performing various actions in response to data entry and gesture-based user interaction. Actions include clicks, button presses, and swipes, all of which determine the flow of the application. The Lightning Component Framework supports these actions and also provides for custom events which allow messaging across loosely coupled independent component instances in an application.
The eventing model in general relies on an ever-present loop that listens for the various events, and fires off associated programmatic logic to handle each event when detected. The Lightning Component Framework uses the JavaScript event loop to listen for events associated with browser-based user actions, as well as other custom events fired from JavaScript code. While the capture and raising of user interface events are automatically managed by the browser, developers are responsible for registering which events to listen for in each component, and for coding the associated JavaScript event handler functions.
The Many Flavors of Lightning Events
The key to mastering event driven programming in the Lightning Component Framework is to clearly understand the different kinds of events handled by the framework, and how to design your apps to use them. There are two primary kinds of events that you will be writing code to handle:
1. User interface events: these fire on a user’s interaction with some HTML element rendered within the user interface of a Lightning Component. Many Lightning tags provide named attributes beginning with “on”, “change”, or “press”, and it is the developer’s job to code JavaScript controller action functions to handle the associated events. Such functions are bound to named attributes using merge expression in the component’s markup, such as press = {!c.doAction}
. That “c.” value provider is a reference to the component’s JavaScript controller, as all such events are both fired and handled within the same component.
2. Lightning Component custom events: these are events fired off from JavaScript code in one component, but typically handled in one or more other Lightning Components that are listening for the event. These types of events are used to facilitate custom messaging across loosely coupled components within an application. Each custom event is defined in a special kind of component called a Lightning Event, each with its own bundle of resources. It is declared in markup, and there are two types: Component events and Application events.
There are two additional kinds of events: Salesforce1 events and System events. While it is important to understand what these are, and when they can be used, our course Creating Lightning Components focuses only on the first two kinds. However, we will address the others briefly in our next and last post in this blog series.
User Interface Events
User interface events are lower level events bound to elements in a component’s markup, activated typically by a user explicitly interacting with that element in the user interface. I say “typically” because it is possible to implicitly fire such an event upon load of a component during its instantiation, as was discussed in a previous post for Module 3.
User interface events fired from the browser are handled by JavaScript action functions in a component’s controller. The action function is bound to named attributes such as onClick, Change or Press of some tag using a merge expression inside a Lightning Component’s markup. It is also possible that the action function may in turn fire some custom Lightning Event as a response to the user interface event.
Controller Action Functions
When a user interface event is fired, the associated controller action function is invoked. Three arguments are automatically passed by dependency injection to the controller’s action function handling the event:
1. Component: a reference to the instance of the Lightning Component container with the markup that fired the event.
2. Event: a reference to the instance of the event that was fired off (such as a click)
3. Helper: a reference to the JavaScript helper function library in the container component
You’ll see how these are used when you watch Module 5: Raising and Handling Events: Part 1 of the course.
Custom Lightning Events
It is important to understand that custom Lightning Events are not the same as user interface events. A custom event is a coded construct that can be declared in markup and explicitly fired and/or handled in JavaScript code. Their primary purpose is to pass messages inside a component or across components, and they might be fired off as a result of some browser-based user interface event. An example of such a custom event might be to cause a refresh of a display of aggregate data in a separate component when a mobile card’s record data is updated.
Custom Lightning Event handling is a little different than user interface event handling. You should think of custom events as notifiers for higher level business or application processes, and their prime purpose is to pass messages across components. They are fired off from one component, and typically handled in another.
There are two types of custom Lightning Events:
Component events: these events are either fired and handled within a single component, or fired from a nested component and handled in its container component. If the latter, the event fired off is handled by an action function in the container component’s JavaScript controller. The binding between the two is declared in the container’s markup, and occurs as the nested component is instantiated inside the container component. We demonstrate this in Module 5 of our course.
Application events: these follow a more traditional publish and subscribe pattern for loosely coupled eventing, and may be fired off by JavaScript functions in a component, either in the controller or the helper. Any component configured as a handler for the event will receive a notification when the event is fired regardless of what component fired it off. Other than the reference to the event itself, there is no other dependency between these components.
Custom Lightning Events must be registered in the markup of any component that is expected to fire off the event from JavaScript within a controller or helper. Components designed to handle custom Lightning Events must also contain markup that designates them as handlers for that event.
You’ll see how custom events are registered, fired and handled when you watch Module 5: Raising and Handling Events: Part 1 of the course.
Events Provide and Promote Loose Coupling
The benefits of custom Lightning Events, and the decoupled model they support for application development, cannot be stressed enough. They permit a development model where components don’t need to know about each other’s existence in an application.
Notifier components, those that fire the custom events, only need concern themselves with firing that event. Nothing fails or breaks if there are no components in the application registered to handle the event. The result is simply that nothing happens when the event fires.
Similarly, handler components, those designed to respond to the events, are simply there listening for it to fire. Again, if no other component fires the event, the result is simply that nothing happens.
While both the notifier and handler components are bound to the event component itself, they do not need to be bound to each other in order to work together in the application; that’s loose coupling at work! In the visual below, Component A as a notifier emits an event, and Components B and D handle it.
Event Attributes as Messages
Developers may declare attributes in their custom Lightning Events to carry data as a message payload. Before the event is fired in JavaScript code, its attributes may be assigned data values to carry as a payload to any handler. Any functions handling the event can read the data from the event’s parameter collection.
Event attributes may be declared as any Lightning data type. While this includes simple primitive types such as string and integer, this also includes complex types such as standard and custom Salesforce objects, collections, Apex custom classes, and even JavaScript data using a variant object type.
It’s a best practice to keep the design of your Lightning Event attribute collections as light-weight as possible. Remember that the basic premise of an object oriented, event driven architecture is to facilitate sending simple messages across objects, and you will benefit in the long term if you avoid unnecessary complexity in your event structures.
Let’s Dig Back In
The eventing model is really very straightforward once you understand the different aspects of the different kinds of events, and when to use each. While it is a more complex and critical aspect of the Lightning Component Framework, it is really not very difficult to master. To see how it works, watch both Module 5: Raising and Handling Events: Part 1, and Module 6: Raising and Handling Events: Part 2.
Related Content
Creating Lightning Components online course
Blog Series:
Creating Lightning Components: Single Page Applications (1 of 6)
Creating Lightning Components: The Bundle as Scaffolding (2 of 6)
Creating Lightning Components: Action Processing and Binding Data (3 of 6)
Creating Lightning Components: Component Based Architecture (4 of 6)
Creating Lightning Components: Events and Messaging (5 of 6)
Creating Lightning Components: Wrapping It Up (6 of 6)
About the Author
Don Robins is a Force.com MVP, Certified Advanced Developer and award winning Salesforce University Certified Instructor. Since 2010, he’s been delivering the core development curriculum to hundreds of customers in both public and private workshops for Salesforce University in the US and abroad. As an independent Training Delivery Partner through his company Forcementor.com, he leads and mentors a team of certified Salesforce instructors, curriculum developers and technical authors. He found his way onto the platform as a consultant and developer in 2009, after two decades of building custom business applications with a metadata, framework-based approach. Ever since, his primary focus has been to educate developers and the business community on Salesforce1 and to evangelize the platform.