[SalesForce] How the values changed in html are reflected in js of lwc

I'm iterating my opportunity list in html which has radio group as input values, now on change of the radio options, my js method is getting called. Inside the js, I'm able to get my selected radio value, but this selected value is not reflecting in my opportunity list.

html:

<template  for:each={OppWrapper} for:item="OppWrap" for:index="ind">
                <tr key={OppWrap.Opp.Id}> 
                    <td>{OppWrap.SerialNumber__c}</td>
                    <td>{OppWrap.Opp.Description__c}</td>
                    <td><lightning-radio-group data-id={ind} type="radio" options={options} value={OppWrap.Status} onchange={handleChanged}></lightning-radio-group></td>    

                </tr>
</template>

js:

    import { LightningElement ,wire,track,api } from 'lwc';
import getWrapper from "@salesforce/apex/OppWrapperController.getWrapper";

export default class lwcWrapper extends LightningElement {

     @api recordId;
    @track OppWrapper;

 @wire(getWrapper, {opportunityId: '$recordId'}) wrapperList ({
        error,
        data
    }) {
        if(data) { 
            this.OppWrapper = [];
            this.OppWrapper = {...data.OpportunityList};//Object.assign({}, data.OppWrapper);
            console.table(">>> data... ",this.OppWrapper);

        } else {
            this.error = error; 
        }

    handleChanged (event){
        let indexNumber = event.target.dataset.id;
        let selectedValue = event.detail;
    }

}

Inner Wrapper Class:

public class InnerWrapper {
    @AuraEnabled
    public Integer serialNumber{get;set;}
    @AuraEnabled
    public Obj1 Oppsc{get;set;}
    @AuraEnabled
    public String Status{get;set;}

    public InnerWrapper(Integer serialNumber,Obj1 Oppsc, String Response) {
        this.serialNumber = serialNumber;
        this.Oppsc = Oppsc;  
        this.Status = Status;
    }   
}

Outer Wrapper Class:

public class OuterWrapper {
    @AuraEnabled
    public Boolean up{get;set;}
    @AuraEnabled
    public Boolean down {get;set;}
    @AuraEnabled
    public Integer OpportunitySum{get;set;}
    @AuraEnabled
    public List<InnerWrapper> OpportunityList = new List<InnerWrapper>();

    public OuterWrapper(Boolean up, Boolean down,Integer BusinessCriteriaSum,
                           Integer OpportunitySum,List<InnerWrapper> OpportunityList){
                               this.up = up;
                               this.down = down;
                               this.OpportunitySum = OpportunitySum;
                               this.OpportunityList = OpportunityList;
                           }
}

Controller Class:

public class  OppWrapperController{

    public static OuterWrapper getWrapper(string opportunityId){
        return OuterWrapper;
    }
}

Now I'm cloning my data, after seeing the answer provided here, but now I'm getting Uncaught (in promise) TypeError: e[ki] is not a function error

Best Answer

There is no two way binding in LWC. The one-way binding is from JS to HTML. Thus whatever radio-button option you are selected is not updated in your opportunityList and thus you have to add that logic in your statusChanged method to update it in opportunityList.

You can follow something similar I did.

<template>
   <template  for:each={opportunityList} for:item="opp" >
                <tr key={opp.Id}> 
                    <td>{opp.Id}</td>
                    <td>{opp.Name}</td>
                    <td >
                        <lightning-radio-group data-id={opp.Id} type="radio" options={options} value={opp.MyPickList} onchange={statusChanged}>

                        </lightning-radio-group>

                        #SELECTED Option : {opp.MyPickList}
                    </td>    

                </tr>
            </template>
</template>

JS Code:

import { LightningElement, track } from 'lwc';

export default class App extends LightningElement {
   @track opportunityList = [ {Id : "000001" ,Name : "Jar" ,MyPickList : ""} , {Id : "000002" ,Name : "Car" ,MyPickList : ""}];

   @track options = [{ label: 'Sales', value: 'Sales Option' },{ label: 'Force', value: 'Force Option' }];

   statusChanged(event){
        let responseBusiness = event.detail; 
        console.log(event.target.dataset.id);
        console.log(responseBusiness);

        //Now updating in the actual opportunityList
        var foundElement =this.opportunityList.find(function (element){
           return element.Id == event.target.dataset.id;
        });
        foundElement.MyPickList = responseBusiness.value;

   }

}

Playground Demo Link : https://developer.salesforce.com/docs/component-library/tools/playground/5_RlTV10E/3/edit

Related Topic