Can't get refreshApex() to work in lwc
I am still trying to find out more on this, but the only way I found refreshApex
to be working by going through one of the examples in lwc-recipe was by refreshing it imperatively as below.
wiredResults;
@wire(getBlasts)
imperativeWiring(result) {
this.wiredResults = result;
if(result.data) {
this.blastData = JSON.stringify(result.data);
}
}
@api
refresh() {
return refreshApex(this.wiredResults);
}
Few observations during my test:
- It seems you cannot utilize the
wireBlastData
function here and that you will need to introduce another function (in my exampleimperativeWiring
) to call the Apex method imperatively - If the same variable
blastData
was utilized in the new function, it resulted in an error (you will be able to view this in console) - Had to introduce a new property (
wiredResults
in this example) and use that in theimperativeWiring
function - Had to make sure that the initialization was as
this.wiredResults = result
. Doing something asthis.wiredResults = result.data
threw an error (this seems to be the reason why it cannot be utilized withwireBlastData
function) - The Apex method was successfully called with this approach, but putting any
alert
orconsole.log
inimperativeWiring
function did not seem to have an effect (I am still not able to figure this out, why!)
Thank you for raising this. I've filed a documentation bug to update Call Apex Methods's Refresh the Cache section with greater clarity.
refreshApex()
operates on the object provisioned by @wire
. That's why code like this works:
import getBlasts from '@salesforce/apex/Blast.getBlasts';
import { refreshApex } from '@salesforce/apex';
export default class BlastWaveTree extends LightningElement {
@wire(getBlasts, { ... })
provisionedValue;
refresh() {
return refreshApex(this.provisionedValue);
}
When you @wire
to a function it is invoked with the provisioned value. When you use object destructuring you're extracting values from the provisioned value, losing the provisioned value itself. Instead you want to do something like this:
import getBlasts from '@salesforce/apex/Blast.getBlasts';
import { refreshApex } from '@salesforce/apex';
export default class BlastWaveTree extends LightningElement {
provisionedValue;
@wire(getBlasts, { ... })
wireBlastData(provisionedValue) {
this.provisionedValue = provisionedValue; // track the provisioned value
const { data, error } = provisionedValue; // destructure it for convenience
if (data) { ... }
else if (error) { ... }
}
refresh() {
return refreshApex(this.provisionedValue);
}
I found your use of JSON.parse/stringify unexpected. Why are you transforming like that instead of returning the desired shape from your Apex class?