0

Why is refresh Apex not working during Inline Edit? When I edit the record, even though the new value gets updated, but in the datatable the old value gets displayed. How can I fix this?

.html

<template>
    <lightning-card>
        <div class="slds-m-top_medium slds-m-bottom_x-large">
            <div class="slds-p-around_medium lgc-bg">
                <lightning-input type="text" label="Search box" placeholder="type here..." value={searchValue} onchange={searchKeyword}></lightning-input>
            </div>
            <lightning-button variant="brand" label="Search" title="Search" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
        </div>
        <div class='slds-m-around_medium'>
            <lightning-datatable
                    key-field='Id'
                   
                    data={records}
                    columns={columns}
                    hide-checkbox-column
                    draft-values={draftValues}
                    onsave={handleSave}>
            </lightning-datatable>
        </div>
    </lightning-card>
</template>

.js

export default class Sample extends LightningElement {
    records;
    error;
    draftValues = [];
    searchValue = '';

    searchKeyword(event){
        this.searchValue = event.target.value;
    }
   handleClick(){
        fetchAccounts({key: this.searchValue})
        .then(result => {
                this.records = result;
        })
        .catch( error=>{
            this.records = null;
        });
    } 

    async handleSave( event ) {

        const updatedFields = event.detail.draftValues;
        const notifyChangeIds = updatedFields.map(row => { return { "recordId": row.Id } });

        await updateAccounts( { data: updatedFields } )
        .then( result => {

            console.log( JSON.stringify( 'Apex update result: ' + result ) );
        
            getRecordNotifyChange(notifyChangeIds);
           refreshApex( this.records).then( () => {
            this.draftValues = [];
            });       

        }).catch( error => {
            console.log( 'Error is ' + JSON.stringify( error ) );
        });

    }

}

Apex

public with sharing class AccountController {
 
    @AuraEnabled( cacheable = true )
    public static List< Account > fetchAccounts(String key) {
     
        return [ SELECT Name FROM Account WHERE Name = :key ];
         
    }

    @AuraEnabled
    public static string updateAccounts( Object data ) {
        
        List < Account > accsForUpdate = ( List < Opportunity > ) JSON.deserialize(
            JSON.serialize( data ),
            List < Account >.class
        );
        try {
            update accsForUpdate;
            return 'Success: Account(s) updated successfully';
        }
        catch (Exception e) {
            return 'The following exception has occurred: ' + e.getMessage();
        }

    }
     
}

1 Answer 1

1

refreshApex refreshs Apex data provisioned via an Apex @wire, indeed the input parameter must be the whole object returned by an Apex @wire.
You're calling an apex method imperatively, so you cannot use refreshApex, instead you have to call the method again.
Docs

Refresh the Cache When Calling a Method Imperatively
To refresh stale Apex data, invoke the Apex method and then call getRecordNotifyChange(recordIds) to update the Lightning Data Service (LDS) cache. Lightning Data Service doesn’t manage data provisioned by imperative Apex calls.

You also don't need async/await in handleSave method.
To fix the issue just replace refreshApex with handleClick:

handleSave(event) {

    const updatedFields = event.detail.draftValues;
    const notifyChangeIds = updatedFields.map(row => { return { "recordId": row.Id } });

    updateAccounts( { data: updatedFields } )
    .then( result => {

        console.log( JSON.stringify( 'Apex update result: ' + result ) );
    
        getRecordNotifyChange(notifyChangeIds);
        this.handleClick();

    }).catch( error => {
        console.log( 'Error is ' + JSON.stringify( error ) );
    });

}

By the way, if you posted the whole code of the component, you don't need to refresh the Lightning Data Service cache calling getRecordNotifyChange in handleSave method, just calling the apex method again is enough.

10
  • The other point is that the imperatively called method should not be marked as cacheable since the data returned does not want to be cached.
    – Phil W
    Commented Jan 2, 2023 at 8:55
  • 1
    Why leave the getRecordNotifyChange in place?
    – Phil W
    Commented Jan 2, 2023 at 8:56
  • @PhilW As per the code posted in the question getRecordNotifyChange can be removed, but I don't know if the OP posted the whole component, nor where it's used, so I gave the benefit of doubt, even if I think it is not needed.
    – RubenDG
    Commented Jan 2, 2023 at 9:04
  • Fair, but worth mentioning in the answer itself.
    – Phil W
    Commented Jan 2, 2023 at 9:15
  • @PhilW edited the answer
    – RubenDG
    Commented Jan 2, 2023 at 9:28

You must log in to answer this question.

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