0

Hi I am trying to send information from Component A to Component X and X to A. I was able to first get the data to send from A to X however upon implementing X to A (which works) A to X no longer works. Is this due to the subscribe function in Component A overwriting the Subscription in Component X?

Component A HTML:

<template>
    <lightning-card title="LWC LMS Component A">
        <div class="slds-m-around_medium">
            <lightning-input type="text" label="Enter message to publish" onkeyup={inputHandler}></lightning-input>
        </div>
        <div class="slds-m-around_medium">
            <lightning-button label="Publish" onclick={publishMessage}></lightning-button>
        </div>
        <div class="slds-m-around_medium">
            Number recieved from X: <strong>{recievedData}</strong>
        </div>
    </lightning-card>
</template>

Component A JavaScript:

import { LightningElement, wire  } from 'lwc';
import SAMPLEMC from "@salesforce/messageChannel/SampleMessageChannel__c"
import { MessageContext, publish, subscribe, APPLICATION_SCOPE } from 'lightning/messageService';

export default class LmsComponentA extends LightningElement {
    inputValue
    recievedData
    subcription

    @wire(MessageContext)
    context

    connectedCallback(){
        this.subscribeTransfer()
    }

    inputHandler(event){
        this.inputValue = event.target.value
    }

    subscribeTransfer(){
        this.subcription = subscribe(this.context, SAMPLEMC, (data)=>{this.recievedData = data.xToAData.receivedNum}, {scope:APPLICATION_SCOPE})
    }

    publishMessage(){
        const message ={
            lmsData:{
                value:this.inputValue
            }
        }
        publish(this.context, SAMPLEMC, message)
    }
}

Component X HTML:

<template>
    <lightning-card title="LWC LMS Component X">
        <div class="slds-m-around_medium">
            <lightning-button label="unsubscribe" onclick={unsubscribeMessage}></lightning-button>
        </div>
        <div class="slds-m-around_medium">
            Message Recieved: <strong>{recievedMessage}</strong>
        </div>
        <div class="slds-m-around_medium">
            <lightning-input type="number" label="Enter a number" class="number-input"></lightning-input>
            <lightning-button variant="base" label="Base" title="Publish To A" onclick={publishNumber} class="slds-m-left_x-small"></lightning-button>
        </div>
    </lightning-card>
</template>

Component X JavaScript:

import { LightningElement, wire } from 'lwc';
import SAMPLEMC from "@salesforce/messageChannel/SampleMessageChannel__c"
import { subscribe, MessageContext, APPLICATION_SCOPE, unsubscribe, publish } from 'lightning/messageService';

export default class LmsComponentX extends LightningElement {
    recievedMessage
    subcription

    @wire(MessageContext)
    context

    connectedCallback(){
        this.subscribeMessage()
    }

    subscribeMessage(){
        this.subcription = subscribe(this.context, SAMPLEMC, (message)=>{this.handleMessage(message)}, {scope:APPLICATION_SCOPE})
    }

    handleMessage(message){
        this.recievedMessage = message.lmsData.value ? message.lmsData.value : 'NO Message published'
    }

    unsubscribeMessage(){
        unsubscribe(this.subcription)
        this.subcription = null
    }

    publishNumber(){
        const data = {
            xToAData:{
                receivedNum:this.template.querySelector("lightning-input").value
            }
        }
        publish(this.context, SAMPLEMC, data)
        
    }
}

Sample Messaging Channel XML:

<?xml version="1.0" encoding="UTF-8" ?>
<LightningMessageChannel xmlns="https://soap.sforce.com/2006/04/metadata">
    <masterLabel>SampleMessageChannel</masterLabel>
    <isExposed>true</isExposed>
    <description>Message Channel to pass data</description>
    <lightningMessageFields>
        <fieldName>lmsData</fieldName>
        <description>This is the field to pass data</description>
    </lightningMessageFields>
    <lightningMessageFields>
        <fieldName>xToAData</fieldName>
        <description>This is to pass number from X to A</description>
    </lightningMessageFields>
</LightningMessageChannel>

1 Answer 1

0

Keep in mind that when you're both a subscriber and a publisher, you're going to receive your own messages. As such, you need to remember to check if the expected data is being received. The following changes should fix your problem.

handleMessage(message) {
    if (message.lmsData) {
        this.recievedMessage = message.lmsData.value || 'NO Message published';
    }
}

...

subscribeTransfer() {
    this.subcription = subscribe(
        this.context,
        SAMPLEMC,
        (data) => {
            if (data.xToAData) {
                this.recievedData = data.xToAData.receivedNum
            }
        },
        { scope: APPLICATION_SCOPE }
    );
}

Note that the "it only works one way" problem was occurring because you were getting errors like "unable to read 'value' from undefined", because you weren't checking if the top-level objects were populated. It so happened that it worked one way, but not the other, because of the order the subscriptions were being processed.

You must log in to answer this question.

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