Uncaught TypeError: ‘set’ on proxy: trap returned falsish for property Name – salesforce lightning web component

When trying to update a field on Contact in JS of Lightning Web Component(salesforce) getting below exception.

Uncaught TypeError: 'set' on proxy: trap returned falsish
for property 'Name' throws at
mydomain/auraFW/javascript/mhontaYdOya4Y_lBu7v9yg/aura_prod.js:2:27687
<template>
    <lightning-card title="Top 10 Contacts" icon-name="custom:custom19">
        <lightning-datatable key-field="Id" data={topcontacts} columns={columns}>
        </lightning-datatable>
    </lightning-card>
</template>
import {LightningElement,wire,track} from 'lwc';
import MyFollowings from '@salesforce/apex/ContactController.fetchContact';
const columns = [{
        label: 'contact Name',
        fieldName: 'Name'
    },
    {
        label: 'email',
        fieldName: 'Email'
    },
    {
        label: 'Account Name',
        fieldName: 'Account.Name'
    },
    {
        label: 'Percentage',
        fieldName: 'Percent_Teaching_Time__c',
        type: "percent"
    }
];
export default class MiscGetUserId extends LightningElement {
    @track topcontacts = [];
    @track columns = columns;
    @wire(MyFollowings)
    followings({
        error,
        data
    }) {
        if (error) {
            // TODO: Error handling
        } else if (data) {
            let myconsData = []; 
            data.forEach((con) => {
  con.Percent_Teaching_Time__c = con.Percent_Teaching_Time__c / 100;
                myconsData.push(this.flatten(con));

            });
            this.topcontacts = myconsData;
            console.log(JSON.stringify(this.topcontacts));
        }
    }
}
public class ContactController {
    @AuraEnabled(cacheable=true)
    public static Contact fetchContact(){
        return [SELECT Id,Name, Percent_Teaching_Time__c, 'Account.Name,Email FROM Contact LIMIT  1];
    }
}

You know you are not doing anything wrong here but why does you get above error? It’s because cached items are set as read-only (otherwise you could corrupt the cache). This is what I could find from the documentation for wired service and that seems to be the case here.

The wire service provisions an immutable stream of data to the component

 So If we want a modifiable object, we need to clone it. Below are few methods how to do it

Method 1:

import {LightningElement,wire,track} from 'lwc';
import MyFollowings from '@salesforce/apex/ContactController.fetchContact';
const columns = [{
        label: 'contact Name',
        fieldName: 'Name'
    },
    {
        label: 'email',
        fieldName: 'Email'
    },
    {
        label: 'Account Name',
        fieldName: 'Account.Name'
    },
    {
        label: 'Percentage',
        fieldName: 'Percent_Teaching_Time__c',
        type: "percent"
    }
];
export default class MiscGetUserId extends LightningElement {
    @track topcontacts = [];
    @track columns = columns;
    @wire(MyFollowings)
    followings({
        error,
        data
    }) {
        if (error) {
            // TODO: Error handling
        } else if (data) {
            let myconsData = [];
    //Clone the data to new object
            let consData = JSON.parse(JSON.stringify(data))
            data.forEach((con) => {
                con.Percent_Teaching_Time__c = con.Percent_Teaching_Time__c / 100;
                myconsData.push(this.flatten(con));

            });
            this.topcontacts = myconsData;
            console.log(JSON.stringify(this.topcontacts));
        }
    }

Parsing data using JSON.parse(JSON.stringify(data)) will solve the above issue. if not you can create a new object and assign all values to it like below

Method 2:

import {LightningElement,wire,track} from 'lwc';
import MyFollowings from '@salesforce/apex/ContactController.fetchContact';
const columns = [{
        label: 'contact Name',
        fieldName: 'Name'
    },
    {
        label: 'email',
        fieldName: 'Email'
    },
    {
        label: 'Account Name',
        fieldName: 'Account.Name'
    },
    {
        label: 'Percentage',
        fieldName: 'Percent_Teaching_Time__c',
        type: "percent"
    }
];
export default class MiscGetUserId extends LightningElement {
    @track topcontacts = [];
    @track columns = columns;
    @wire(MyFollowings)
    followings({
        error,
        data
    }) {
        if (error) {
            // TODO: Error handling
        } else if (data) {
            let myconsData = [];           
            data.forEach((con) => {
                 let conData = new Object();
                 console.log(con.Account.Name);
                 conData.Name = con.Name;
                 conData.Email = con.Email;
                 conData.aName = con.Account.Name;
                 conData.Percent_Teaching_Time__c = con.Percent_Teaching_Time__c / 100;
                myconsData.push(conData);

            });
            this.topcontacts = myconsData;
            console.log(JSON.stringify(this.topcontacts));
        }
    }
}

Let us know if any of these methods doesnt solve your problem.

Happy coding 🙂

2 comments

  1. I have exact same problem with lightning-datatable. However in my case, i am getting columnsData from a parent component. I tried to assign the data to a new object in the connectedCallback of the datatable component but apparently during the connectedCallback(), columnsData is not populated. Any ideas how to fix this?

    Like

Leave a comment