Author: Shrikant Raut
In today’s world of evolving technologies, it is very important to have an underlying functionality that binds both the older/legacy and new/evolving technologies. Considering the Salesforce ecosystem, it initially started with Visualforce/Apex pages which then evolved to Lightning AURA components and now we have Lightning Web Components(LWC). Thinking of some huge legacy system that was built long back when Visualforce was in use, now when such a system needs enhancements or new implementations, developers/architects worried about the backward compatibility of AURA or LWC tend to go for Visualforce since it was built using the same. But what if I say, there is an underlying tool that can be leveraged to maintain connectivity between all three of them(Visualforce, AURA & LWC), it is known as Lightning Message Service(LMS).
Applications:
LMS can be leveraged to communicate across components residing almost anywhere, following are some of the examples:
- Console Tabs
- Standard App Tabs
- Lightning Tabs
- Utility Bar Items
- Background Utility Items
- Minimized Utility Items
- Hidden – Tabs, Sub-Tabs, App-Tabs
Lightning Message Channel:
- LMS provides a secure event bus that helps in passing data across components, we call it the Message Channel.
- Message Channel represents a secure channel through which the data(messages) will be passed across components in the DOM.
- It is a light weight, packageable component that can be created/deployed in salesforce.
Assuming a SFDX project already created with authorization of a dev org.
- Create directory named “messageChannels” under “force-app\main\default” folder.
- Create a file with extension “.messageChannel-meta.xml”
- <messageChannelName>.messageChannel-meta.xml
- Ex . demoMessageChannel.messageChannel-meta.xml
- Deploy this metadata to the org.
Given below is the body of a sample Message Channel, where lightningMessageFields tag holds the field names. Actual data will be passed through these message fields. (You can have multiple fields in a single channel, as per your needs)
<?xml version=”1.0″ encoding=”UTF-8″?>
<LightningMessageChannel xmlns=”http://soap.sforce.com/2006/04/metadata”>
<description>This Lightning Message Channel is used for demo purpose</description>
<isExposed>true</isExposed>
<lightningMessageFields>
<description>Holds name of the source cmp publishing the message</description>
<fieldName>source</fieldName>
</lightningMessageFields>
<lightningMessageFields>
<description>Holds actual message</description>
<fieldName>data</fieldName>
</lightningMessageFields>
<masterLabel>demoMessageChannel</masterLabel>
</LightningMessageChannel>
Implementation:
There are 3 important methods for implementing LMS across any type of component in salesforce. (syntax given below is for LWC but the methods and relevance will remain the same across)
- createMessageContext() – This returns a MessageContextObject
- publish(messageContext, messageChannel, message/payload)
PARAMETER | TYPE | DESCRIPTION |
messageContext | object | Provides information about the component using the LMS.Get this via MessageContext wire adapter or via createMessageContext() |
messageChannel | object | The message channel object, use the scoped module @salesforce/messageChannel. |
message/payload | object | JSON object payload |
- subscribe(messageContext, messageChannel, listener/callback, subscriberOptions(optional))
PARAMETER | TYPE | DESCRIPTION |
messageContext | object | Provides information about the component using the LMS.Get this via MessageContext wire adapter or via createMessageContext() |
messageChannel | object | The message channel object, use the scoped module @salesforce/messageChannel. |
listener | function | A callback function that handles the message once published. |
subscriberOptions | object | (Optional) An object that, when set to {scope: APPLICATION_SCOPE}, specifies the ability to receive messages on a message channel from anywhere in the application. Import APPLICATION_SCOPE from lightning/messageService. |
The usage and implementation of the above methods vary based on the type of the component(VF, AURA, LWC) LMS is being implemented for.
LMS in Lightning Web Components (LWC)
Access Message Channel with the scoped module ’@salesforce/messageChannel’
import { subscribe, unsubscribe, publish, MessageContext, APPLICATION_SCOPE } from ‘lightning/messageService’;
import messageChannel from ‘@salesforce/messageChannel/demoMessageChannel__c’;
Imports
- subscribe
- unsubscribe
- publish
- MessageContext
- messageChannel
- APPLICATION_SCOPE
LMS in AURA Components (AURA)
Access Message Channel using lightning:messageChannel tag
<lightning:messageChannel type=”demoMessageChannel__c” onMessage=”{!c.handleChange}”/>
Attributes
- type
- onMessage
- scope
No need for a separate subscription, it is implicit when lightning:messageChannel handler is provided
Same lightning:messageChannel tag is to be used by both subscriber and publisher
LMS in Visualforce Pages (VF)
Access Message Channel using $MessageChannel global variable
{!$MessageChannel.demoMessageChannel__c}
Standard sforce.one functions
- publish
- subscribe
- Unsubscribe
Considerations:
Supported experiences/features
- Lightning Experience standard navigation
- Lightning Experience console navigation
- Salesforce mobile app for Aura and Lightning Web Components
- Lightning components used in Experience Builder sites.
Lightning message service doesn’t support
- Visualforce pages in mobile apps
- Lightning Communities
- Message Channel creation from Salesforce user interface
Demo:
Find the working code for the above example here.