Passing Data From One Lightning Web Component to Another Lightning Web Component

|
| By Webner

Sometimes there is a requirement to pass data from one LWC to another which are not in the same DOM tree i.e they are not linked to each other so for that earlier we used to use the pubsub library but now Salesforce has come up with ‘Lightning Message Service’.

LMS is a standard publish-subscribe library that is used for making communication between Lightning Web Components (LWC), Aura Components, and even Visualforce Pages. The advantage of this above pubsub is it can be used across pages, tabs or even pop-up windows and is not restricted to a single page.

The publish-subscribe model works in such a way that one component publishes an event and the other subscribe and handles it. Let’s check out the way to send data using Lightning Message Service in LWC.

Message Channel

The first step is to create a Message Channel which is an xml file. You cannot make it using Salesforce developer console but can easily make it using VS Code and Salesforce CLI. For this, you first need to create a folder named messageChannels, in the force-app/main/default folder. In that folder, you need to create a new file like “SampleMessageChannel.messageChannel-meta.xml”. The ‘SampleMessageChannel’ can be any name you want to keep according to your requirement. If you have a namespace being used in your organization then it will be “namespace__SampleMessageChannel.messageChannel-meta.xml”. The structure of the file needs to be like
<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
<masterLabel>MyMessageChannel</masterLabel>
<isExposed>true</isExposed>
<description>This Lightning Message Channel sends information from LWC to LWC</description>
<lightningMessageFields>
<fieldName>messageToSend</fieldName>
<description>message To Send</description>
</lightningMessageFields>
<lightningMessageFields>
<fieldName>sourceSystem</fieldName>
<description>My source?</description>
</lightningMessageFields>
</LightningMessageChannel>

The masterLabel tag is used to give a name to the message channel; in this case, it will be “MyMessageChannel.” The lightningMessageField tag defines the fields that will contain the value you want to pass to the other component. You can use multiple lightningMessageField tags if you want to send multiple data as shown in the example above. The isExposed tag is used to set value for allowing the Message Channel to be used across namespaces. Once the file is created in the above manner then you can deploy it to the Org.

Publishing the data to Message Channel

The second step is to publish the data to the Message Channel for that you will have to create a component which will be the publisher. In the component’s Javascript file you will first include the elements needed from the lightning/messageService module and then the Message Channel that you created. In this example, we imported the publish and MessageContext from the messageService and the MessageChannel Created.
import { publish, MessageContext } from 'lightning/messageService';
//Import the definition for subscribe, unsubscribe, Scope and context of the message
import MyMessageChannel from '@salesforce/messageChannel/MyMessageChannel__c';

After the imports are done you need to create the message context. You can either do this by creating the createMessageContext() method or, if the component extends LightningElement, you can use the subsequent syntax:
@wire(MessageContext)
messageContext;

Now you need to publish the data to the Channel using the “publish” method.
const message = {
messageToSend: “Hello” ,
sourceSystem: “LWC”
};
publish(this.messageContext, MyMessageChannel, message);

The publish method includes three arguments: the message context, the message channel, and the message. A message is an object which contains the fields from the Message Channel file which you want to publish.

Subscribing to Message Channel

The last step is the subscriber end i.e the receiver end in which you will have to make a component that will subscribe to the data published by the first component and for this, you will have to receive the subscribe, unsubscribe APPLICATION_SCOPE and MessageContext from the messageService and the MessageChannel Created.
import {subscribe,unsubscribe,APPLICATION_SCOPE,MessageContext } from 'lightning/messageService';
//Import the definition for subscribe, unsubscribe, Scope and context of the message
import MyMessageChannel from '@salesforce/messageChannel/MyMessageChannel __c';

Once you are done with the imports you will have to create the MessageContext the same way as you did in the publisher component.

Lastly, you will need to create the subscribe method for the subscription of the messages. This also includes three arguments: the message context, the message channel, and callback to be executed when the subscription is received from the message channel. This is done as shown below.
@track messageRecieved;
@track sourceSystem;
connectedCallback(){
this.subscribeMsg();
}
subscribeMsg() {
if (this.subscription) {
return;
}
this.subscription = subscribe(this.messageContext, MyMessageChannel , (message) => this.handleMessage(message),{ scope: APPLICATION_SCOPE });
}
handleMessage(message) {
this.messageRecieved = message.messageToSend;
this.sourceSystem = message.sourceSystem;
}

Once you have received the data you are now set to use it anywhere in the component you want. Here is a code that is added for when the component is removed from the DOM. It simply unsubscribes from the subscription made above so as to not keep any connection with the MessageChannel.
unsubscribeMC() {
unsubscribe(this.subscription);
this.subscription = null;
}
disconnectedCallback() {
this.unsubscribeMC();
}

Leave a Reply

Your email address will not be published. Required fields are marked *