Child to Grandparent Event Communication in LWC
Events are actions or occurrences that happen in the system. In LWC, these Javascript events are used to communicate from child to parent or beyond.
There are three main ways to fire event from child to grandparent.
- CustomEvent
By default, Events don’t propagate beyond the shadow root of the component instance. However, setting Event.bubbles and Event.composed allows event pass through the shadow boundary.
let event = new CustomEvent('message',{
detail: {
value: this.value
},
bubbles: true,
composed: true
});
this.dispatchEvent(event)
In Grandparent compoent, simply add event handler for the fired event.
<template>
<c-parent-component onmessage={handleMessage}></c-parent-component>
</template>
LWC Event Best Practices: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.events_best_practices
- Lightning Message Service (LMS)
In the Winter ’20, Salesforce introduced LMS to communicate across DOM between LWC, Aura and Visualforce pages. Comparing topubsub
it not restricted to a single page. Any component in a Lightning Experience application that listens for events on a message channel updates when it receives a message.
- Step 1: Create a Message Channel
First step to use LMS is creation of Lightning message channel. It should be placed under force-app/main/default/messageChannels/.
TestMessageChannel.messageChannel-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
<description>This is a Test Lightning Message Channel</description>
<isExposed>true</isExposed>
<lightningMessageFields>
<description>This is the message</description>
<fieldName>message</fieldName>
</lightningMessageFields>
<masterLabel>TestMessageChannel</masterLabel>
</LightningMessageChannel>
Declarative Metadata Sample Definition: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_lightningmessagechannel.htm
- Step 2: Publish on Message Channel
To publish messages on a message channel from a Lightning web component, include the @salesforce/messageChannel module and call the Lightning message service’s publish() function.
childComponent.js
import { LightningElement, wire } from 'lwc';
import messageChannel from '@salesforce/messageChannel/TestMessageChannel__c';
import {publish, MessageContext} from 'lightning/messageService'
export default class ChildComponent extends LightningElement {
@wire(MessageContext)
messageContext;
handleClick(){
let message = {messageText: 'the message'};
publish(this.messageContext, messageChannel, message);
}
}
- Step 3: Subscribe to Message Channel
To subscribe on a message channel, import the message channel from the @salesforce/messageChannel module and call the Lightning message service’s subscribe().
grandparentComponent.js
import { LightningElement, wire } from 'lwc';
import messageChannel from '@salesforce/messageChannel/TestMessageChannel__c';
import { subscribe, MessageContext } from 'lightning/messageService';
export default class GrandparentComponent extends LightningElement {
subscription = null;
@wire(MessageContext)
messageContext;
connectedCallback() {
this.subscribeToMessageChannel();
}
subscribeToMessageChannel() {
if (!this.subscription) {
this.subscription = subscribe(this.messageContext, messageChannel, (message) => {
console.log(`grand parent received ${message.messageText}`);
});
}
}
}
The Lightning message service supports only the following experiences:
- Lightning Experience standard navigation
- Lightning Experience console navigation
- Salesforce mobile app for Aura and Lightning Web Components, but not for Visualforce pages
- Lightning components used in Experience Builder sites. Support for Experience Builder sites is beta.
- pubsub Module
This component was a temporary solution for lack of feature-parity between LWC and Aura components related to cross-DOM messaging. As of July 2020, c/pubsub has been superseded by the Lightning Message Service. However, this is still usefull where Lightning Message Service has limitations.
More info: https://github.com/developerforce/pubsub