14

Please note that this is not duplicate of LWC Force Refresh Wire getRecord - this question and answer specifically speaks about changes in front-end/UI and capturing that in front-end BUT LDS cannot listen to database changes to record and so we need to manually refresh LDS record cache.

Question:

According to documentation of refreshApex, if we know that record has been updated in database, we can invoke refreshApex to re-invoke and refresh the cached response of Apex method response.

But for wired service getRecord, there is no such method to manually refresh the cache and it refreshes the cache only after 30 seconds from last fetching the record ( - if invoked within or after 30 seconds). If I know that the record has been updated in the database through some backend transaction (like workflow), how can we manually refresh cache of getRecord?

3 Answers 3

19

To make refreshApex clear the client-side cache it is necessary to capture and store the entire result from the getRecord wire. In this case you cannot define your handler to accept an anonymous object with data and error properties.

You need to do something like the following. First add a private property to hold the result:

_getRecordResponse;

Then update the handling of the getRecord wire response from something like:

@wire(getRecord, {...})
receiveRecord({error, data}) {
    ...
}

to:

@wire(getRecord, {...})
receiveRecord(response) {
    this._getRecordResponse = response;
    let error = response && response.error;
    let data = response && response.data;
    ...
}

Now that you have the _getRecordResponse, you can force the record to be reloaded by calling:

refreshApex(this._getRecordResponse);
2
  • 1
    Worth also noting you might be able to listen for changes in the backend using the Emp service - basically using streaming API and a change event.
    – Phil W
    Commented Sep 26, 2019 at 9:27
  • 2
    Thanks Phil!, when I tried this implementation before, I was not getting log and so thought its not refreshing. I answered for that part below Commented Sep 26, 2019 at 10:04
7

Extending answer from @Phil W,

For below Sample LWC Js:

@api recordId = '00128000009j45tAAA';
@track wiredAccount;

fields = [ACCOUNT_NAME_FIELD, ACCOUNT_DESCRIPTION_FIELD];

@wire(getRecord, { recordId: '$recordId', fields: '$fields' })
fetchAcc(response) {
    console.log('Account => ', JSON.stringify(response));
    this.wiredAccount = response;
}

refreshWire() {
    refreshApex(this.wiredAccount);
}

Although we invoke refreshWire, the wired method fetchAcc will be invoked ONLY if new record and UI record in this.wiredAccount are not same and consecutively see the console log. If the new record is same as UI record this.wiredAccount, the method fetchAcc will not be invoked (even after 30 seconds) and we will not see any console log. Finally, refreshApex should have been named refreshWire as it not just updates apex method response but also wired service response.

4
  • refreshApex is, I would presume, called refreshApex because both imperative and wired calls are fundamentally both just calling a (cacheable) AuraEnabled Apex method. The difference with a wired service is that there is client-side logic for handling caching (and for detecting changes to wired "reactive" parameters for re-invocation).
    – Phil W
    Commented Sep 26, 2019 at 10:25
  • @PhilW So, you mean getRecord is internally apex method in lightning namespace ? Commented Sep 26, 2019 at 10:31
  • Yeah, I would think so. It seems like Salesforce is generally pretty good at using its own plumbing to implement stuff. Obviously I can't guarantee this since I've not seen the code, but it makes sense to do it this way.
    – Phil W
    Commented Sep 26, 2019 at 10:49
  • crap.. this is good.. I was doing eval('$A.force.refreshView`) Commented Sep 26, 2019 at 15:52
0

We can use notifyRecordUpdateAvailable to refresh data from getRecord.

notifyRecordUpdateAvailable([{recordId: this.theRecordId}]);

About notifyRecordUpdateAvailable: To refresh stale Apex data, invoke the Apex method and then call notifyRecordUpdateAvailable(recordIds) to update the Lightning Data Service (LDS) cache. Lightning Data Service doesn’t manage data provisioned by imperative Apex calls. After you invoke the Apex method, call notifyRecordUpdateAvailable(recordIds) to signal to Lightning Data Service that some records are stale and refresh those records in the cache.

For detail: you can refer to https://developer.salesforce.com/docs/platform/lwc/guide/apex-result-caching.html

You must log in to answer this question.

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