0

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:

LWC table component for editable related list LWC table component for editable related list - picklist dropdown

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));
    }

console.log output

1

This type of error(Cannot assign to read-only property) generally occurs on update of public property @api decorator variable value.

As I see from your code you are trying to update pfList property, Check if this public property(@api), If So change into @track or clone the pfList into a new variable.

EDIT

let tempPickList  = this.pfList

tempPickList.map(e =>{
if(e.Id === uniqueKey){
 e.Registration_Type__c = pickValue;
}
})

//Check if the value is updated.
console.log(tempPickList)
this.pfList = tempPickList 
3
  • pfList is already a @track property. I tried the clone option too, the error doesn't pop up, but I'm not getting the expected result. I have updated my post - please see my description below "Analysis of clone option". – Dhivya Uday Mar 24 '20 at 17:50
  • @DhivyaUday I do see pfList is List of JSON, you have to loop through the JSON to match the key and update the JSON. I edit my answer – Sarvesh Mar 25 '20 at 6:09
  • pfList is actually list of child records of Opportunity that I am fetching from Salesforce through a controller, and I am iterating through that list to display the records in the related list. I used JSON.stringify just to display the data in the developer console. Anyway, I tried your logic, and it doesn't let me update tempPickList either. I have updated my post by adding the controller code and the initial logic in javascript to load the related list contents. – Dhivya Uday Mar 25 '20 at 13:38
1

@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:

let tempPickList  = JSON.parse(JSON.stringify(this.pfList));

tempPickList.map(e =>{
    if(e.Id === uniqueKey){
         e.Registration_Type__c = pickValue;
    }
})

//Check if the value is updated.
console.log(tempPickList)
this.pfList = tempPickList

Thank you for your idea!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.