I am building an editable related list using LWC. I need to render percent, picklist, text and lookup fields in the related list. I am stuck on the picklist child component – unable to save the newly selected picklist value.
Component screenshots:
Code snippets:
HTML code-snippet where I include the picklist child component:
<template for:each={pfList} for:item="item" for:index="indexVar">
<tr key={item.Id} class="slds-hint-parent" ondblclick={onDoubleClickEdit}>
<td class="slds-size_1-of-11" data-label="Prospecting">
<div title="Prospecting">
<template if:false={isEdited}>
{item.Registration_Type__c}
</template>
<template if:true={isEdited}>
<c-picklist
unique-key={item.Id}
object-api-name="Portfolio__c"
record-type-id={item.RecordTypeId}
selected-value={item.Registration_Type__c}
pick-listfield-api-name="Registration_Type__c"
variant="label-hidden"
onpicklistchange={handlePicklistChange}>
</c-picklist>
</template>
</div>
</td>
</tr>
</template>
Javascript code-snippet (parent component code):
import fetchPortfoliosFromOpps from '@salesforce/apex/OppPortfoliosController.getPortfoliosForOpp';
@track pfList = [];
_wiredResult;
@wire(fetchPortfoliosFromOpps, { recordId: "$recordId" })
wiredCallback(result) {
console.log('****entered wiredCallback');
this._wiredResult = result;
if (result.data) {
this.pfList = result.data;
this.error = undefined;
for(var key in result.data){
console.log('***key: '+key);
console.log('***result.data[key]: '+result.data[key]);
this.pfMap.push({value: result.data[key], key: key});
console.log('***this.pfMap: '+this.pfMap);
}
}
else if (result.error) {
this.error = result.error;
this.pfList = undefined;
}console.log('****JSON.stringify(this.pfList): '+JSON.stringify(this.pfList));
}
handlePicklistChange(event){
let eventData = event.detail;
let pickValue = event.detail.selectedValue;
let uniqueKey = event.detail.key;
// 1. console.log('pickValue: '+pickValue);
// 2. console.log('uniqueKey: '+uniqueKey);
let element = this.pfList.find(ele => ele.Id === uniqueKey);
// 3. console.log('before element.Registration_Type__c: '+element.Registration_Type__c);
// 4. console.log('element extensible?: '+Object.isExtensible(element));
// 5. Object.assign(element.Registration_Type__c, pickValue);
// 6. this.pfList.Registration_Type__c = {...pickValue};
element.Registration_Type__c = pickValue;
console.log('after element.Registration_Type__c: '+element.Registration_Type__c);
this.pfList = [...this.pfList];
}
Controller Code:
@AuraEnabled(cacheable = true)
public static List<Portfolio__c> getPortfoliosForOpp(String recordId){
System.debug('****Entered getPortfoliosForOpp() recordId: '+recordId);
return [SELECT Id, RecordTypeId, Equity_Target__c, Bond_Target__c, Registration_Type__c, Fee_Type__c, Fee_Schedule__c,
Discretionary__c, Billing_In__c, Proxy_Voting_by_Us__c, Revenue_Source__c, Custodian__c, Custodian__r.Id,
Custodian__r.Name, Custodian__r.CustodianUrl__c, ManagedNew__c, PortfolioUrl__c
FROM Portfolio__c WHERE Opportunity__c =: recordId];
}
I am able to select a new value from the picklist dropdown, but I'm unable to save it back to the Registration_Type__c field on the object using the code:
element.Registration_Type__c = pickValue
I get the error: [Cannot assign to read only property 'Registration_Type__c' of object '#']
I looked up for ways to overcome this error, but couldn't figure anything yet. I tried #5 and #6 (commented statements in the above JS code) which gave a similar error.
Console statements output:
1: displays the new picklist value that I select
2: give the id of the row I edit on the table
3: Old picklist value (the value that existed before my new selection)
4: false
Any ideas on how this can be fixed, and the reason why the property is in read-only mode?
Analysis of clone option:
I tried to clone the list, but I am unable to get pfList updated, which I would require in the save button function.
handlePicklistChange(event){
let eventData = event.detail;
let pickValue = event.detail.selectedValue;
let uniqueKey = event.detail.key;
console.log('pickValue: '+pickValue);
console.log('uniqueKey: '+uniqueKey);
let element = Object.assign({}, this.pfList);
console.log('before this.pfList = [...this.pfList]: '+this.pfList.find(ele => ele.Id === uniqueKey).Registration_Type__c);
element.Registration_Type__c = pickValue;
console.log('after element.Registration_Type__c: '+element.Registration_Type__c);
this.pfList = [...this.pfList];
console.log('after this.pfList = [...this.pfList]: '+this.pfList.find(ele => ele.Id === uniqueKey).Registration_Type__c);
console.table(JSON.stringify(this.pfList));
}
Best Answer
@Sarvesh : I dug a little deeper into your solution and replaced
let tempPickList = this.pfList
with
let tempPickList = JSON.parse(JSON.stringify(this.pfList));
I am able to update pfList now! Yeayy!
Updated code-snippet:
Thank you for your idea!