Lightning Message Service

Lightning Message Service

In this blog post, we would be creating Visualforce, Aura Component and Lightning Message Service and exchanging messages between all of them using Lightning Message Service.

Introduction to Lightning Message Service

  • Introduced in the Winter ’20 release by Salesforce, Lightning Message Service is the out-of-the-box functionality that empowers you to communicate between Visualforce and Lightning Components, including Aura web components (AWC) and Lightning web components (LWC).
  • For an organization hesitant to migrate to Lightning Experience and its newer technologies, Aura Components and Lightning Web Components.
  • LMS may make the migration palatable. With LMS’s ability to communicate between Visualforce pages and lighting components, you can take a more disciplined approach to upgrading.
  • Instead of scraping existing Visualforce pages and creating new Lightning components, you can update existing Visualforce pages to interact with new Lightning components to provide new functionality.

What is a Lightning Message Service?

  • LMS is defined as the standard publish-subscribe library that enables communication quickly and seamlessly with DOM across the Salesforce UI tech stack, including Visualforce Pages, Aura components, and Lightning Web Components (LWC) using simple API.
  • With this unique feature of Salesforce, you can publish messages and subscribe to them anywhere within the lightning page.
  • Lightning Message Service feature is similar to Aura application events that enable seamless communication between components.
  • Lightning Message Service is based on Lightning Message Channels, a new metadata type. 
  • Lightning Message Channel is used to access the Lightning Message Service API and Lightning Message Channel in LWC via scoped module @salesforce/messageChannel. When it comes to Visualforce, you can use the global variable $MessageChannel.
  • In Aura, you can use lightning:messageChannel in your component.

 

 

Uses Of Lightning Message Service :

  • To enable communication between Visualforce page, Lightning web components, and Aura components, 
  • To access Lightning Message Service API for publishing messages throughout Lightning Experience.
  • It helps in subscribing to messages that originated from anywhere within Lightning Experience via Lightning Message Channel. 
  • A specific namespace is associated with Lightning Message Channel. Developers can choose whether they want their message channel to be available to other namespaces or not, ensuring the security of communication on Lightning Message Service.

Lightning Message Channel :

  • It’s basically the name of Schema which will hold the actual message.
  • create file LMSDemoWin.messageChannel-meta.xml in folder messageChannels.

<?xml version=”1.0″ encoding=”UTF-8″?>
<LightningMessageChannel xmlns=”http://soap.sforce.com/2006/04/metadata”>
   <masterLabel>LMS Demo</masterLabel>
   <isExposed>true</isExposed>
   <description>Winter 20 – LMS Demo.</description> 
</LightningMessageChannel>

 

Deploy Lightning Message Channel :

  • Run below SFDX command to deploy this message channel on your Salesforce Org.
  • Run push command to deploy message channel on Orgs.
  • Once, Lightning Message Channel is created, let’s start by creating components and first we will create below Visualforce Page.

 

<apex:page>
    <!– Begin Default Content REMOVE THIS –>
    <h1>Lightning Message Services – Demo – Winter 20</h1>
    <div>
        <p>Message To Send</p>
        <input type=”text” id=”vfMessage” />
        <button onclick=”publishMessage()”>Publish</button> 
        <br/> 
        <button onclick=”subscribeMC()”>Subscribe</button> 
        <button onclick=”unsubscribeMC()”>Unsubscribe</button> 
        <br/>
        <p>Messages Received:</p>
        <textarea id=”txtMessages” rows=”2″ style=” width:100%;” />
    </div>
    <script> 
        // Load the MessageChannel token in a variable
        var lmsDemoChannel = “{!$MessageChannel.LMSDemoWin__c}”;
        var subscriptionToMC;
       function publishMessage() {
            const payload = {
                source: “Visualforce”,
                messageBody: document.getElementById(‘vfMessage’).value
            };
            sforce.one.publish(lmsDemoChannel, payload);
        }
        function subscribeMC() {
            if (!subscriptionToMC) {
                subscriptionToMC = sforce.one.subscribe(lmsDemoChannel, onMCPublished);
            }
        }
        function unsubscribeMC() {
            if (subscriptionToMC) {
                sforce.one.unsubscribe(subscriptionToMC);
                subscriptionToMC = null;
            }
        }
        function onMCPublished(message) {
            var textArea = document.querySelector(“#txtMessages”);
            textArea.innerHTML = message ? ‘Message: ‘ + message.messageBody + ‘ From: ‘ + message.source : ‘no message payload’;
        } 
    </script>
</apex:page>
  • Next component we would build would be the Aura Component.

 

<aura:component description=”testMessageAura” implements=”flexipage:availableForAllPageTypes” access=”global”>
    <aura:attribute type=”String” name=”myMessage”/>
    <aura:attribute type=”String” name=”receivedMessage”/>
    <lightning:messageChannel type=”LMSDemoWin__c” aura:id=”lmsDemohannel” onMessage=”{!c.handleReceiveMessage}”/>
    <lightning:card title=”Aura Component” iconName=”custom:custom18″>
        <div class=”slds-m-around_medium”>
            <lightning:input type=”text” value=”{!v.myMessage}” label=”Message To Send”/>
            <lightning:button label=”Publish” onclick=”{! c.handleClick}”/>
            <br/>
            <br/>
            <p>Latest Received Message</p>
            <lightning:formattedText value=”{!v.receivedMessage}”/>
        </div>
    </lightning:card>
</aura:component>

 

  • Controller of Aura Component

 

({
    handleClick: function(component, event, helper) {
        let myMessage = component.get(“v.myMessage”);
        const payload = {
            source: “Aura Component”,
            messageBody: myMessage
        };
        component.find(“lmsDemohannel”).publish(payload);
    },
    handleReceiveMessage: function (component, event, helper) {
        if (event != null) {
            const message = event.getParam(‘messageBody’);
            const source = event.getParam(‘source’);
            component.set(“v.receivedMessage”, ‘Message: ‘ + message + ‘. Sent From: ‘ + source);
        }
    }
});

 

  • Aura Component by default handles those operations once we declare them.
  • Last component we would be creating is the Lightning Web Component.

 

<template>
    <lightning-card title=”LWC” icon-name=”custom:custom18″>
        <div class=”slds-m-around_medium”>
            <lightning-input label=”Message To Send” type=”text” value={_msg} onchange={handleChange}></lightning-input>
            <lightning-button label=”Publish” onclick={handleClick}></lightning-button>
            <br>
            <lightning-button label=”Subscribe” onclick={handleSubscribe}></lightning-button>
            <lightning-button label=”Unsubscribe” onclick={handleUnsubscribe}></lightning-button>
            <p> Message Received</p>
            <lightning-formatted-text value={receivedMessage}></lightning-formatted-text>
        </div>
    </lightning-card>
</template>
  • Javascript of LWC

 

import { LightningElement, track} from ‘lwc’;
import { publish,createMessageContext,releaseMessageContext, subscribe, unsubscribe } from ‘lightning/messageService’;
import lmsDemoMC from “@salesforce/messageChannel/LMSDemoWin__c”;
export default class LMS_MessageSenderReceiverLWC extends LightningElement {
    @track _msg = ”;
    @track receivedMessage = ”;
    channel;
    context = createMessageContext();
    constructor() {
        super();
    }
    handleSubscribe() {
        const parentPage = this;
        this.channel = subscribe(this.context, lmsDemoMC, function (event){
            if (event != null) {
                const message = event.messageBody;
                const source = event.source;
                parentPage.receivedMessage = ‘Message: ‘ + message + ‘. Sent From: ‘ + source;
            }
        });
    }
    handleUnsubscribe() {
        unsubscribe(this.channel);
    }
    handleChange(event) { 
        this._msg = event.target.value;
    }
    handleClick() {  
        const payload = {
            source: “Lightnign Web Component”,
            messageBody: this._msg
        }; 
        publish(this.context, lmsDemoMC, payload);
    } 
    disconnectedCallback() {
        releaseMessageContext(this.context);
    }
}

 

  • Once we embed all three components (Visualforce, Aura and Lightning Web Components), we would be able to see Lightning Message Service in action as shown in below image.

 

 

Advantage of Lightning Message Service :

  • One of the significant benefits is increased development time. For instance, if a Visualforce Page or Lightning component tries to reference a message channel that is non-available and that message channel is not exposed, then the code would not compile. 
  • This messaging service offers referential integrity between the code that references them and the message channel.
  • It restricts the deletion of message channels, which are referenced by other codes. Further, Lightning Message Service supports auto-adding message channels to packages.
  • As the metadata type is packageable, you can associate a message channel to a particular namespace and make it available/unavailable to other namespaces.