I have a datatable which displays records retrieved from api. one of the columns is editable (and is blank on load). One of the issues I have is that i cannot use the refreshApex because the data don't exist in the database yet. So, when the column is edited and saved, i would like to update the current table data.


const COLUMNS = [
{ label: 'Ref', fieldName: 'ref',  type: 'text' },
{ label: 'Dril Date', fieldName: 'drilDate', type: 'text' },
{ label: 'Dril Amount', fieldName: 'drilAmount', type: 'text' },
{ label: 'Description', fieldName: 'description', type: 'text', editable: true }];

To do this, I have tried:

handleSave(event) {
    for(var i = 0; i < this.data.length; i++) {
        let draftValues = this.template.querySelector('lightning-datatable').draftValues;
        for(var d = 0; d < draftValues.length; d++){
            let rowId = draftValues[d].id.slice(draftValues[d].id.lastIndexOf('-') + 1);
            if(i == rowId){
                let dataRow = {...this.data[rowId], ...{description: draftValues[d].description}};
                this.data[rowId] = {...this.data[rowId], dataRow};
    this.draftValues = [];

however, this throws NoErrorObjectAvailable error

1 Answer 1


It's not immediately obvious to be why you'd get this error, but I can say you'll get abysmal performance if you try this with too many rows in LWC in Salesforce, because of the Locker Service overhead. Your code should look something more like this:

handleSave() {
  this.data = [...this.data];
  this.template.querySelector('lightning-datatable').draftValues.forEach((value) => { 
    let index = this.data.findIndex(row => row.id === value.id);
    this.data[index] = { ...this.data[index], ...value };

We first copy the array to trigger a refresh, then for each draftValue, we find the row with findIndex, and then copy the values to the index. This will also perform far better than your code in Locker Service.

You must log in to answer this question.

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