1

I have a LWC which takes value from 3 input fields and passes the value to a separate component with lightning datatable via LMS. I am able to pass the data for the first time but when I try to repeat the process all the values in the array are updated to the latest value.

Publisher Component HTML:

<template>
    <lightning-card title="Input Data">
        <lightning-input class="slds-m-around_medium" type="text" data-id="name" label="Enter Name" onchange={inputHandler}></lightning-input>
        <lightning-input class="slds-m-around_medium" type="text" data-id="phone" label="Enter Phone" onchange={inputHandler}></lightning-input>
        <lightning-input class="slds-m-around_medium" type="text" data-id="country" label="Enter Country" onchange={inputHandler}></lightning-input>
        <lightning-button class="slds-m-around_medium" label="Send Data" variant="brand" onclick={dataHandler}></lightning-button>
    </lightning-card>
</template>

Publisher Component JS:

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import SEND_MESSAGE from '@salesforce/messageChannel/Send_Message__c';

export default class DataFiller extends LightningElement {


name;
phone;
country;

@wire(MessageContext)
messageContext;

records=[];
data={};

inputHandler(event){
    if(event.target.dataset.id == 'name'){
        this.name = event.target.value;
        this.data.Name = this.name;
        console.log(this.data);
    }
    else if(event.target.dataset.id == 'phone'){
        this.phone = event.target.value;
        this.data.Phone = this.phone;
        console.log(this.data);
    }
    else{
        this.country = event.target.value;
        this.data.Country = this.country;
        console.log(this.data);
    }
}

dataHandler(){
    this.records.push(this.data);
    let payload = this.records;
    publish(this.messageContext, SEND_MESSAGE, payload);
}

Subscriber Component HTML:

<template>
    <lightning-card title="Person Details">
        <lightning-datatable columns={columns} key-field="Id" data={data}>           
        </lightning-datatable>
    </lightning-card>
</template>

Subscriber Component JS:

import { LightningElement, wire } from 'lwc';
import { subscribe, MessageContext } from 'lightning/messageService';
import SEND_MESSAGE from '@salesforce/messageChannel/Send_Message__c';

export default class PersonTable extends LightningElement {

    columns = [{ label : 'Name', fieldName: 'Name'},
                 { label : 'Phone', fieldName: 'Phone'},
                 { label : 'Country', fieldName: 'Country'}];

    data;
    subscription=null;

    @wire(MessageContext)
    messageContext;

    subscriptionToMessageChannel(){
        this.subscription=subscribe(this.messageContext, SEND_MESSAGE, (messageToSend) => this.handleMessage(messageToSend));
    }

    connectedCallback(){
        this.subscriptionToMessageChannel();
        console.log('Subscribed');
    }

    handleMessage(messageToSend){
        this.data = messageToSend;
        console.log(JSON.stringify(this.data))
    }

}

When the data is send for the First time

When the data is sent for the second time

2 Answers 2

1

You are not resetting data variable due to that same value adding again.

We can get all value on button click.

In below code snippet we are query input with latest LWC update lwc:ref.

HTML file

<template>
    <lightning-card title="Input Data">
        <lightning-input class="slds-m-around_medium" type="text" label="Enter Name" lwc:ref="name"></lightning-input>
        <lightning-input class="slds-m-around_medium" type="text" label="Enter Phone" lwc:ref="phone"></lightning-input>
        <lightning-input class="slds-m-around_medium" type="text" label="Enter Country" lwc:ref="country"></lightning-input>
        <lightning-button class="slds-m-around_medium" label="Send Data" variant="brand" onclick={dataHandler}></lightning-button>
    </lightning-card>
</template>

JS file

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import SEND_MESSAGE from '@salesforce/messageChannel/Send_Message__c';
export default class Component1 extends LightningElement {
    name;
    phone;
    country;

    @wire(MessageContext)
    messageContext;

    records=[];

    dataHandler(){
        let name = this.refs?.name?.value;
        let phone = this.refs?.phone?.value;
        let country = this.refs?.country?.value;
        this.records.push({Name : name, Phone : phone, Country : country});
        publish(this.messageContext, SEND_MESSAGE, this.records);
    }
}

Output: Output

Ref : https://help.salesforce.com/s/articleView?id=release-notes.rn_lwc_templaterefs.htm&release=242&type=5

1

data is never reset, so you're pushing the same object onto the Array. You need to make a new object every time you want a new row.

dataHandler(){
    this.records.push(this.data);
    let { name: Name, phone: Phone, country: Country } = this;
    this.data = { Name, Phone, Country };
    let payload = this.records;
    publish(this.messageContext, SEND_MESSAGE, payload);
}

If you want to preserve the input for some reason, do so by copying, instead:

    this.data = {...this.data};
3
  • First solution will not help here because if we reset variable then when we click on button again then it will not get value from input.
    – A.K.
    Commented Aug 25, 2023 at 19:51
  • @A.K. That's a separate issue, though I suppose I should mention here. Thanks for the feedback.
    – sfdcfox
    Commented Aug 25, 2023 at 20:02
  • Thank you both. The answer is really helpful and I am able to resolve it.
    – code234
    Commented Aug 26, 2023 at 4:57

You must log in to answer this question.

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