Tuesday, April 30, 2024

Communicate Between Unrelated LWC Components- Lightning Message Service (LMS)

LMS is a publish and subscribe service that helps communicating between LWC, Aura components, and Visualforce pages. 

In this, first we have to defined channels called as messaging channel to define attributes through which we can publish information. Both the components (publisher and subscriber) needs to import this channel. Consider message channel as protocol through which information will be shared between 2 components.

In order to define messaging channel, you have create a folder named as "messageChannels" under default folder in VS code.



Now create a new file named as "enquiry_sender.messageChannel-meta.xml". You can give any name to file but make sure that it has extension as ".messageChannel-meta.xml".

In this xml file you define, lightningMessageFields and its description. These fields names will be used to used information from one component to another.


Note: 

If you are getting a validation error for the XML, then turn XML validation off.

In VS Code, click File > Preferences > Settings (Windows) or Code > Settings > Settings (macOS). Search for Validation. Select XML and uncheck Validation.

Now we have defined a message channel, lets use it to publish and subscriber message.

Publish LMS

In order to publish message using this channel, we need to import LMS and channel that we created

import { publish, MessageContext } from 'lightning/messageService';
import SEND_ENQUIRY_CHANNEL from '@salesforce/messageChannel/Enquiry_Sender__c';

Use below syntax to publish the LMS:

    @wire(MessageContext)
    messageContext;
    const payload = {
            email: 'sk@gmail.com',
            phone: '0123456789'
          };
          console.log('***payload:'+JSON.stringify(payload));
          publish(this.messageContext, SEND_ENQUIRY_CHANNEL, payload);


Subscribe LMS

In order to subscribe LMS, subscribing also need to import LMS and channel that we have been created for communication.

import { subscribe, MessageContext } from 'lightning/messageService';
import SEND_ENQUIRY_CHANNEL from '@salesforce/messageChannel/Enquiry_Sender__c';

Use below syntax to subscribe LMS:

    @wire(MessageContext)
    messageContext;
    subscribeToLMS() {
        this.subscription = subscribe(
        this.messageContext,
        SEND_ENQUIRY_CHANNEL,
        (message) => this.handleMessage(message)
        );
    }
    handleMessage(message) {
        console.log('**recieved message:'+JSON.stringify(message));
    }

    connectedCallback() {
        this.subscribeToLMS();
    }

In this way information can be passed between 2 LWC components which are not related to each other.

I have created 2 LWC components for demo purpose to show how it works. In first LWC component (userEnquiry), we take email and phone from user and when he clicks on send button, a message is published. Now we have another LWC component (contactCheck) which will subscribe to send_enquiry__c channel. 

So whenever first component will publish message, another LWC component will display information send by first component.




Below is complete code for reference:


Note:
LMS is powerful, effective, and easy to use, but use it only if it is necessary. Firing DOM events is much more efficient and should be first preference.

Hope this will help!!