1

I have created LMS to pass the payload between 2 LWC. Message payload is published but payload is not getting received on the subscriber component.

Publish LWC is located on Opportunity Record Page. Subscriber LWC is located on Opportunity Product Record Page.

Please find the code: Message Channel XML:

<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
   <masterLabel>productSapAccountMessageChannel</masterLabel>
   <isExposed>true</isExposed>
   <description>This Lightning Message Channel sends selected SAP Accounts to Products LWC</description>
</LightningMessageChannel>

Publisher LWC JS:

import { LightningElement, wire, api } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import PRODUCT_SAPACCOUNT_Message from "@salesforce/messageChannel/productSapAccountMessageChannel__c";

export default class publisherLWC extends NavigationMixin(LightningElement) {
  //Load the context for Lightning Messaging Service 
    @wire(MessageContext) messageContext; 

     handleButtonClick(){
        //Publish Selected Accounts to Message Channel
        const message = {AccountsDetails: 'Hello'}; 
        publish(this.messageContext, PRODUCT_SAPACCOUNT_Message, message);
        console.log('message' + message);
    }

}

Subscriber LWC:

import { subscribe, MessageContext } from 'lightning/messageService';
import PRODUCT_SAPACCOUNT_Message from "@salesforce/messageChannel/productSapAccountMessageChannel__c";

export default class subscriberLWC extends LightningElement {
   productSelectionSubscription;

    //Wire the MessageContext with a variable
    @wire(MessageContext)
    messageContext;

     connectedCallback(){
       //Subscribe to Messaging Channel
        this.subscribeToMessageChannel();
     } 

     //Subscribe to Messaging Channel 
    subscribeToMessageChannel() {
        console.log("subscribing");
        
        this.productSelectionSubscription = subscribe(
            this.messageContext,
            PRODUCT_SAPACCOUNT_Message,
            (message) => this.handleMessage(message)
        );
    }

    handleMessage(message) {
        console.log('Inside handle Message');
        console.log("received " + JSON.stringify(message));   -------> Need help here as  
               message is not getting printed in console. 
    }
}

Message payload is published but it is not getting subscribed. Subscribe function is not getting called.

Any kind of help is appreciated.

Thank you.

2 Answers 2

1

By subscribing and publishing in connectedCallback(), you're relying on your components being initialized in a specific order. In other words, based on the rendering graph, your component might not be subscribed in time. To ensure that it is, wait to publish on the next render cycle:

async connectedCallback(){
    await Promise.resolve(); // Wait one lifecycle.
    //Publish Selected Accounts to Message Channel
    const message = {AccountsDetails: 'Hello'}; 
    publish(this.messageContext, PRODUCT_SAPACCOUNT_Message, message);
    console.log('message' + message);
}
5
  • Thank you @sfdcfox for your reply. I tried with the solution you suggested but still not able to receive the payload message in the subscriber component. Thank you.
    – Rose
    Commented Nov 3, 2022 at 15:07
  • @sfdxfox I have changed my code and now I'm publishing it on a button click event. But still message is not subscribed.
    – Rose
    Commented Nov 3, 2022 at 15:31
  • 1
    @Rose I just realized you said the components are on two different pages. That might be a reason why it's not working. If you need to store data temporarily, try using window.sessionStorage to store and load values between the pages.
    – sfdcfox
    Commented Nov 3, 2022 at 15:39
  • Thank you for your reply. I will try with window.sessionStorage to store and load values between the pages.
    – Rose
    Commented Nov 3, 2022 at 15:41
  • @sfdxfox, I tried with localstorage and it worked. I have posted the answer also. I have one question, for particular recordId it worked but it overrides with the value if we select new recordId. I would like to show selected accounts for particular recordId. For different records values stored in localstorage is overriden with latest record selected. Thank you.
    – Rose
    Commented Nov 3, 2022 at 21:05
1

I tried with localstorage and it worked. Please find the code:

Opportunity LWC:

export default class OpportunityLWC extends NavigationMixin(LightningElement) {
   
    //Get Selected Checkbox for SAP Accounts 
    handleRowSelection(event) {
        var selectedRows=event.detail.selectedRows;
        this.selectedSapAccounts = JSON.stringify(selectedRows); 
        
        console.log('selectedSAPAccounts------>' + this.selectedSapAccounts);

        //Set LocalStorage 
        localStorage.setItem('SelectedSAPAccountsDetails', this.selectedSapAccounts);
    
        if(selectedRows.length === 0){
            this.disabled = true;
        }else{
            this.disabled = false;
        }
    }

}
Opportunity Product LWC JS:

export default class OpportunityProductLWC extends LightningElement {
        
accountColumns = [
        {
            label: 'SAP Account Name',
            fieldName: 'AccountName',
            type: 'url',
            typeAttributes: {label: { fieldName: 'Name' }, target: '_blank'}
        },
        { label: 'Type', fieldName: 'Type__c', type: 'string'},
        { label: 'Division', type: 'text', fieldName: 'Division__c'}
    ];

 connectedCallback(){
 //Retrieve the localStorage Values 
        this.retrieveLocalStorage();
}

retrieveLocalStorage(){
        
        if(localStorage.getItem('SelectedSAPAccountsDetails')){
            
            this.localStorageSelectedSAPAccountDetails = localStorage.getItem('SelectedSAPAccountsDetails');

            //Retrieve the data and parse it back to JSON
            console.log('localstorage--->' + this.localStorageSelectedSAPAccountDetails);
            
            this.sapAccounts = 
       JSON.parse(this.localStorageSelectedSAPAccountDetails);;

            //Clear local storage after getting the values
            localStorage.clear();
        }

         
    }

}
Opportunity Product HTML

<template>
    <div>
        <lightning-card title="">
          <div class="slds-p-around_xx-small">
              <lightning-datatable
                  key-field="Id"
                  data={sapAccounts}
                  onrowselection={handleRowSelection}
                  onsave={handleSave}
                  draft-values={saveDraftValues}
                  hide-checkbox-column="true" 
                  show-row-number-column="true"
                  columns={accountColumns}>
              </lightning-datatable>
          </div>
        </lightning-card>
      </div>
</template>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .