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.

  1. 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>
Warning

This configuration bubbles your event all the way to the document root, it can cause name collisions which can cause the wrong event listeners to fire. Therefore, above mechanism is not recomended, unless required.

LWC Event Best Practices: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.events_best_practices

  1. Lightning Message Service (LMS)
    In the Winter ’20, Salesforce introduced LMS to communicate across DOM between LWC, Aura and Visualforce pages. Comparing to pubsub 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:

  1. Lightning Experience standard navigation
  2. Lightning Experience console navigation
  3. Salesforce mobile app for Aura and Lightning Web Components, but not for Visualforce pages
  4. Lightning components used in Experience Builder sites. Support for Experience Builder sites is beta.
Info

Lightning Message Service doesn’t work with Salesforce Tabs + Visualforce sites or with Visualforce pages in Experience Builder sites.

  1. 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

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.