html code

Facilitating Communication Across Salesforce UI Technologies with Lightning Message Service

There are lot of issue in communication between Visual Force Pages, Lightning Component and Lightening Web Component.  We used to use Window object to communicate between these pages.

Salesforce has introduce Lightning Message Service API in Winter’20 to communicate across the DOM, between Aura components, Visualforce pages, and Lightning web components. If application switching from Salesforce Classic to Lightning Experience, we can now build Lightning web components that can communicate with existing Visualforce pages or Aura components.

A Lightning web component uses a Lightning Message Channel to access the Lightning Message Service API. Reference Lightning Message Channel with the scoped module @salesforce/messageChannel. In Visualforce, use the global variable $MessageChannel. In Aura, use lightning:messageChannel in your component.

Situations where Lightning Message Service can be employed include:

In Lightning Experience, it’s common to have multiple components on a single page. Previously, to enable communication between a Visualforce page and a Lightning web component within Lightning Experience, a custom publish-subscribe solution had to be devised. However, with the introduction of the Lightning Message Service API, this communication can now be seamlessly managed.

Implementation Guidelines:

Let us take example, we have created a message channel called SampleMessageChannel__c using the Metadata API.  See how a message channel is published in Lightning web component and subscribed in Visual Force Page.

Create a Lightning web component called publisherComponent that publishes on SampleMessageChannel__c, which is the API name of the message channel. The component imports methods to publish on a message channel from the lightning/messageService module. This module accesses the Lightning Message Service API.

Next, import the message channel from @salesforce/messageChannel/SampleMessageChannel__c and assign it to the identifier SAMPLEMC.

// publisherComponent.js
import { LightningElement } from 'lwc';
import { publish,createMessageContext,releaseMessageContext } from 'lightning/messageService';
import SAMPLEMC from "@salesforce/messageChannel/SampleMessageChannel__c";

export default class MyLwcPublisher extends LightningElement {
    context = createMessageContext();
    constructor() {
        super();
    }
    handleClick() {
        const message = {
            recordId: "some string",
            recordData: {
                value: "some data"
            }
        };
        publish(this.context, SAMPLEMC, message);
    }
    disconnectedCallback() {
        releaseMessageContext(this.context);
    }
}

The handleClick() method holds the data to be published on the message channel. In this example, the data is a recordId with the value “some string” and recordData, whose value is the key-value pair value: “some data”. Publish the data by calling the publish()method imported from the lightning/messageService module.

In component’s HTML template file, include a Publish button that calls the handleClick() method. Clicking the button publishes the record data to SampleMessageChannel__c. The subscribing Visualforce page then receives that data.

<-- publisherComponent.html -->
<template>
    <lightning-card title="MyLwcPublisher" icon-name="custom:custom14">
        <div class="slds-m-around_medium">
            <p>MessageChannel: SampleMessageChannel</p>
            <br>
            <lightning-button label="Publish" onclick={handleClick}></lightning-button>
        </div>
    </lightning-card>
</template>

Recipient (Visualforce Page):

We can subscribe and unsubscribe a Visualforce page from a message channel SampleMessageChannel__c on which a Lightning web component publishes.

<apex:page>
    <div>
        <p>Subscribe to SampleMessageChannel</p>
        <button onclick="subscribeMC()">Subscribe</button>
        <p>Unsubscribe from SampleMessageChannel</p>
        <button onclick="unsubscribeMC()">Unsubscribe</button>
        <br/>
        <br/>
        <p>Received message:</p>
        <textarea id="MCMessageTextArea" rows="10" style="disabled:true;resize:none;width:100%;"/>
    </div>
    <script>
        // Load the MessageChannel token in a variable
        var SAMPLEMC = "{!$MessageChannel.SampleMessageChannel__c}";
        var subscriptionToMC;
        // Display message in the textarea field
        function onMCPublished(message) {
            var textArea = document.querySelector("#MCMessageTextArea");
            textArea.innerHTML = message ? JSON.stringify(message, null, '\t') : 'no message payload';
        }

        function subscribeMC() {
            if (!subscriptionToMC) {
                subscriptionToMC = sforce.one.subscribe(SAMPLEMC, onMCPublished);
            }
        }

        function unsubscribeMC() {
            if (subscriptionToMC) {
                sforce.one.unsubscribe(subscriptionToMC);
                subscriptionToMC = null;
            }
        }
    </script>

</apex:page>