Start tracking your progress
Trailhead Home
Trailhead Home

Communicate with Events

Learning Objectives

After completing this unit, you’ll be able to:
  • Describe differences in events for the two programming models.
  • Send an event from a Lightning web component to an Aura component.

A component walled off by itself can be useful, but the real app magic happens when components start talking to each other. That’s where events come in. Using events to communicate between components is a web standard, and events are central to communication in both Aura components and Lightning web components.

Component Events Become DOM Events

Migrate component events in Aura components to web-standard DOM events in Lightning web components. If you’re familiar with DOM events, you notice the same propagation behavior in Lightning web components.

Create and Dispatch an Event

Instead of the proprietary Event object in Aura components, use the Event or CustomEvent standard DOM interfaces. We strongly recommend you use the CustomEvent interface, because this provides a more consistent experience. The framework may need to patch properties and methods of events to normalize implementations between browsers, and using CustomEvent guarantees that your component is covered. Internet Explorer doesn’t support the CustomEvent interface natively, but the Lightning Web Components model adds support for it.

There’s no equivalent in Lightning web components for the <aura:registerEvent> tag in Aura component markup to register that a component can fire an event. Thanks to using standard DOM events, this extra ceremony isn’t needed.

Instead of event.fire() in an Aura component, use the standard DOM method, this.dispatchEvent(myEvent), in Lightning web components.

Here’s an example of creating and dispatching (firing) an event in the propertyTile Lightning web component.

export default class PropertyTile extends LightningElement {
    @api property;

    propertySelected() {
        const selectedEvent = new CustomEvent('selected', {
            detail: this.property.Id,
        });
        this.dispatchEvent(selectedEvent);
    }
}

The first argument in the CustomEvent() constructor sets the name of the event to selected.

The second argument is an object that configures the event behavior. In this object, we set the detail, which is the data payload for the event. A handling component can read the data. In this case, we’re passing the this.property.Id value.

Handle an Event

An Aura component uses the <aura:handler> tag in markup to define a handler. Alternatively, a component can declare a handler action when it references another component in its markup.

This Aura component uses c:child in its markup and declares a handleNotification handler for the notification event that c:child fires.

<c:child notification="{!c.handleNotification}"/>

A Lightning web component can similarly have a declarative handler. The event name in the declarative handler is prefixed by on.

<c-child onnotification={handleNotification}></c-child>

The handleNotification event handler function is defined in the JavaScript file of the component.

In a Lightning web component, you can also programmatically set up a handler using the standard addEventListener() method in the component’s JavaScript file.

Let’s look at how the DreamHouse app handles the selected event created and dispatched in the propertyTile Lightning web component. The propertyTileList Lightning web component handles this event in its HTML file.

<template for:each={properties} for:item="property">
    <c-property-tile property={property} key={property.Id} onselected={onPropertySelected}></c-property-tile>
</template>

The selected event name is prefixed by on in the declarative handler configured by onselected={onPropertySelected}.

The onPropertySelected event handler function is defined in propertyTileList.js.

onPropertySelected(event) {
    pubsub.fire('propertySelected', event.detail);
}

Cast your mind back to when we fired the selected event in propertyTile. The CustomEvent() constructor set detail to this.property.Id. The handler unpacks the event data by accessing event.detail. In this example, we get the property ID in event.detail.

We explain what’s going on with pubsub.fire() when we look at application events next.

Application Events Become a Publish-Subscribe Pattern

Migrate application events in Aura components to a pub-sub (publish-subscribe) pattern in Lightning web components. In a pub-sub pattern, one component publishes an event and other components subscribe to receive and handle the event. Every component that subscribes to the event receives the event.

Standard DOM events should always be your first choice for events because they only travel up the containment hierarchy, making behavior more predictable. Application events can be problematic in complex apps because any component can handle the event. This pattern can lead to code that is hard to maintain due to unexpected coupling of components. However, sometimes you need sibling components in a containment hierarchy to communicate. Unrelated components used in Lightning pages or the Lightning App Builder are examples of sibling components that need to communicate. In those scenarios, the pub-sub pattern is the way to go.

The DreamHouse app uses a pubsub.js module. Feel free to copy the pubsub module and use it in your code.

The pubsub module exports three methods.

register
Registers a callback for an event.
unregister
Unregisters a callback for an event.
fire
Fires an event to listeners.

Sending Events to an Enclosing Aura Component

Lightning web components dispatch DOM events. An enclosing Aura component can listen for these events, just like an enclosing Lightning web component can. The enclosing Aura component can capture the event and handle it. Optionally, the Aura component can fire an Aura event to communicate with other Aura components or with the app container.

This technique is useful when you want to support events or interfaces that are used in Aura components but not currently supported by Lightning web components.

The following example illustrates this technique. This Lightning web component fires a custom notification event in its JavaScript file.

// catchAndRelease.js
import { LightningElement } from 'lwc';

export default class CatchAndRelease extends LightningElement {
    /**
     * Handler for 'Fire My Toast' button.
     * @param {Event} evt click event.
     */
    handleFireMyToast(evt) {
        const eventName = 'notification';
        const event = new CustomEvent(eventName, {
            detail: { message: 'See you on the other side.' }
        });
        this.dispatchEvent(event);
    }
}

The enclosing Aura component wrapper adds a handler for the custom event. Notice that the event handler, onnotification, matches the event name with on prefixed to it. That is, use onnotification to handle the event named notification.

<!-- catchAndReleaseWrapper.cmp -->
<aura:component implements="force:appHostable">
    <c:catchAndRelease onnotification="{!c.handleCustomEvent}"/>
</aura:component>
Note

Note

You can only specify an onnotification handler in the first Aura component that the DOM event bubbles to.

The handleCustomEvent function in the controller of the catchAndReleaseWrapper Aura component handles the event.

// catchAndReleaseWrapperController.js
({
    handleCustomEvent: function(cmp, evt) {
        // Get details from the DOM event fired by the Lightning web component
        var msg = evt.getParam('message') || '';
    }
})

The notification event dispatched by the Lightning web component set the event detail.

detail: { message: 'See you on the other side.' }

The Aura component that handles the event accesses the event data using evt.getParam('message').

You can handle the event however you’d like. You can optionally fire a new Aura event to communicate with other Aura components.

Resources

That’s a Wrap!

We’ve thrown many concepts at you, but you should have a better understanding now of how Aura components map to Lightning web components. The best way to learn more is to play around with code. Here are some ideas for next steps:

  • Explore the DreamHouse app code to see how all the components fit together.
  • Check out the lwc-recipes repo on GitHub to see lots of tasty code samples for common use cases.
  • See more sample apps in the Sample Gallery.
  • Click the Playground tab in the Component Library and start playing around with your own components.

Even if you hit a few traffic jams or unexpected diversions along the way, we hope you enjoy the journey!

But What About…?

Unfortunately, there’s a limit to the amount of material that we can cover in one Trailhead module. A module is like a bucket of water. There’s only so much water that you can pour in before it starts to overflow. If we opt for a bigger bucket, it becomes too heavy to carry around.

If we didn’t cover a feature that you’re interested in, it’s not because we didn’t want to. The bucket is simply full.

Testing Components

In particular, we didn’t cover the important area of component testing. Here are some pointers to further information in the developer guides.

In Aura components, use Lightning Testing Service to test components.

In Lightning web components, use Jest for unit testing. If Jest doesn’t cover all your test cases, use Lightning Testing Service to cover the remaining test cases. See Test Lightning Web Components.

Aura Methods Become JavaScript Methods

Migrate methods from <aura:method> tags in an Aura component to JavaScript methods with an @api decorator in a Lightning web component.

Use a JavaScript method to communicate down the containment hierarchy. For example, a parent component calls a method on a child component that it contains. Methods are part of a component’s API.

To learn more, see Call Methods on Child Components in the Lightning Web Components Developer Guide.

Migrate Interfaces

The primary usage of interfaces in Aura components is for marker interfaces, which enable specific usage for a component in an app. A marker interface is an empty interface with no attributes, events, or methods.

In Lightning web components, usage is defined in a component’s configuration file or with some simple @api decorators.

For more details, see Migrate Interfaces in the Lightning Web Components Developer Guide.

Migrate Access Controls

To manage access to an Aura bundle’s resources, such as a component or attribute, use the access system attribute.

The mechanism for access control is different in a Lightning web component, where access is defined by JavaScript property decorators and the component’s configuration file.

For more details, see Migrate Access Controls in the Lightning Web Components Developer Guide.