How to Handle Events in LWC

How to Handle Events in LWC : Lightning web components dispatch standard DOM events. Components can also create and dispatch custom events.

Use events to communicate up the component containment hierarchy. For example, a child component, example-todo-item, dispatches an event to tell its parent, example-todo-app, that a user selected it.

Events in Lightning web components are built on DOM Events, a collection of APIs and objects available in every browser.

Lightning web components implement the EventTarget interface, which allows them to dispatch events, listen for events, and handle events.

To create events, we strongly recommend using the CustomEvent interface instead of the Event interface. In Lightning web components, CustomEvent provides a more consistent experience across browsers, including Internet Explorer.

Dispatching events or adding listeners to the capture phase isn’t supported. Simply think of the event’s path as starting with your component, and then moving to its parent, and then grandparent, and so on.

How to Handle Events in LWC

There are two ways to listen for an event: declaratively from the component’s HTML template, or programmatically using an imperative JavaScript API. It’s better to listen from the HTML template since it reduces the amount of code you need to write.

To handle an event, define a method in the component’s JavaScript class.

How to Attach Event Listeners Declaratively

This example uses two components in the example namespace, <example-owner> and <example-child>.

The child component has an HTML button, which emits a standard click event.

<!-- child.html -->
<template>
    <button>Click Me</button>
</template>

To listen for an event, a component uses an HTML attribute with the syntax oneventtype. In the template of the owner component, to listen for the click event emitted from <example-child>, declare the listener onclick.

<!-- owner.html -->
<template>
    <example-child onclick={handleClick}></example-child>
</template>

In the JavaScript class of the owner component, define the handleClick method, which executes when the click event fires.

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

export default class Owner extends LightningElement {
    handleClick(e){
        // Your code here
    }
}

How to Attach Event Listeners in JavaScript

Alternately, you can define both the listener and the handler in the owner component’s JavaScript file.

<!-- parent.html -->
<template>
    <example-child></example-child>
</template>
<!-- child.html -->
<template>
    <button>Click</button>
</template>

Get a reference to <example-child> using this.template.querySelector. To handle the event, define handleClick in the JavaScript file of the owner.

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

export default class App extends LightningElement {
    renderedCallback(){
        this.template.querySelector('example-child').addEventListener('click',
         this.handleClick);
    }

    handleClick(e){
        // Your code here
    }
}

There are two syntaxes for adding an event listener. One adds an event listener to an element within a component’s shadow boundary. One adds an event listener to an element that the template doesn’t own, for example, an element passed into a slot.

To add an event listener to an element within the shadow boundary, use template.

this.addEventListener()

In the previous example, the parent.js code uses this.template syntax to select example-child because example-child is within its shadow boundary. An event listener added via this.template.addEventListener has access to bubbling events inside the shadow tree.

To add an event listener to an element that a template doesn’t own, call addEventListener directly.

An event listener added via this.addEventListener binds to the host element and has access to events on the host element and to any bubbling events from slotted content. It doesn’t have access to events inside the shadow tree. See Pass Markup into Slots.

Remove Event Listeners

As part of the component lifecycle, the browser manages and cleans up listeners, so you don’t have to worry about it.

However, if you add a listener to the global window object, you’re responsible for removing the listener yourself within the appropriate lifecycle hook. In this case, use the connectedCallback and disconnectedCallback methods to add and remove the event listeners.

How to Create and Dispatch Events

Create and dispatch events in a component’s JavaScript class. To create an event, use the CustomEvent() constructor. To dispatch an event, call the EventTarget.dispatchEvent() method.

The CustomEvent() constructor has one required parameter, which is a string indicating the event type. As a component author, you name the event type when you create the event. The event type is the name of the event. You can use any string as your event type. However, we recommend that you conform with the DOM event standard.

  • No uppercase letters
  • No spaces
  • Use underscores to separate words

Don’t prefix your event name with the string on, because inline event handler names must start with the string on. If your event is called onmessage, the markup would be <example-my-component ononmessage={handleMessage}>. Notice the doubled word onon, which is confusing.

Let’s jump into some code.

The paginator component contains Previous and Next buttons. When a user clicks a button, the handlePrevious or handleNext function executes. These functions create and dispatch the previous and next events. You can drop the paginator component into any component that needs Previous and Next buttons. That component listens for the events and handles them.

paginator.js

import { LightningElement } from 'lwc';

export default class Paginator extends LightningElement {
    handlePrevious() {
        this.dispatchEvent(new CustomEvent('previous'));
    }

    handleNext() {
        this.dispatchEvent(new CustomEvent('next'));
    }
}

paginator.html

<template>
  <div>
    <button onclick={handlePrevious}>Previous</button>
    <button onclick={handleNext} class="right">Next</button>
  </div>
</template>

paginator.css

.right {
    float: right;
}

These events are simple something happened events. They don’t pass a data payload up the DOM tree, they simply announce that a user clicked a button.