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 example imperativeWiring) 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 the imperativeWiring function
  • Had to make sure that the initialization was as this.wiredResults = result. Doing something as this.wiredResults = result.data threw an error (this seems to be the reason why it cannot be utilized with wireBlastData function)
  • The Apex method was successfully called with this approach, but putting any alert or console.log in imperativeWiring 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?