1

I have a datatable lwc that displays data returned from an apex method. When I edit the data and hit on save , the data table doesn't refresh automatically and the cell value remains the same although the record gets updated. When I reload my record page, where my lwc is placed,only then I am able to see the updated table. Below is my lwc:

JS:

import { LightningElement, wire, track, api } from 'lwc';
import getOpportunityRecs from '@salesforce/apex/OpportunityApex.getOpportunityRecs';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';

const columns = [{label: 'Opportunity Name',fieldName: 'opName',type: 'url',typeAttributes: {label: { fieldName: 'Name' },target: '_blank'},sortable: true},
                {label: 'Stage',fieldName: 'StageName',type: 'text',editable: true}, 
                {label: 'Contact Phone',fieldName: 'Contact_Phone__c',type: 'phone',editable: true}];

export default class LWCDatatable extends LightningElement {

    columns = columns;
    @track isLoaded = false;
    
    @api recordId;
    
    @track opRecsList;
    saveDraftValues = [];
    
    @wire(getOpportunityRecs,{recordId: '$recordId'})
    WiredRecords(result) {
        const { data, error } = result;
        if(data) {
            let opName;
            this.opRecsList = data.map(row => { 
                opName = `/${row.Id}`;
                return {...row , opName} 
            })
            this.error = null;
        }
        if(error) {
            this.error = error;
            //this.opRecsList = [];
            this.opRecsList = undefined;
        }
    }

    async handleSave(event) {
        this.saveDraftValues = event.detail.draftValues;
        const recordInputs = this.saveDraftValues.slice().map(draft => {
            const fields = Object.assign({}, draft);
            return { fields };
        });

        this.isLoaded = true;

        const promises = recordInputs.map(recordInput => updateRecord(recordInput));
        Promise.all(promises).then(res => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                    message: 'Updated Successfully!',
                    variant: 'success'
                })
            );

            this.isLoaded = false;
            return this.refresh();
        }).catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error',
                    message: 'An Error Occured!!',
                    variant: 'error'
                })
            );
        }).finally(() => {
            setTimeout(() => {
            }, 3000);
            this.saveDraftValues = [];
        });
    }

    async refresh() {
        await refreshApex(this.opRecsList);
    }

}

Html:

<template>
    <lightning-card title="Lwc Datatable" icon-name="standard:user">
        <template if:true={isLoaded}>
            <lightning-spinner alternative-text="Loading" variant="brand" size="small"  >
            </lightning-spinner>
        </template>
        <template if:true={opRecsList}>
            <lightning-datatable key-field="Id" 
                                 data={opRecsList} 
                                 columns={columns} 
                                 onsave={handleSave}
                                 draft-values={saveDraftValues}
                                 max-row-selection=1
                                 onrowselection={handleRowSelection}>
            </lightning-datatable>
        </template>
        <template if:true={error}>
            {error}
        </template>
    </lightning-card>
</template>

What am I missing here?

1 Answer 1

1

So, turns out refreshApex works on the result as a whole provided from the wire and not simply on the data. So, I am posting my updated code below:

@wire(getOpportunityRecs,{recordId: '$recordId'})
    WiredRecords(result) {
        this.opRecsList = result;
        const { data, error } = result;
        if(data) {
            let opName;
            result.data = data.map(row => { 
                opName = `/${row.Id}`;
                return {...row , opName} 
            })
        }
        if(error) {
            this.error = error;
        }
    }

and now my datatable is refreshing automatically after save!! I hope this helps anybody else who may be facing a similar issue.

You must log in to answer this question.

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