Skip to main content
Bumped by Community user
Bumped by Community user
deleted 32 characters in body
Source Link
Robs
  • 9.4k
  • 21
  • 119
  • 224
  1. What on earth is going on?
  2. Am I going crazywrong? :o)
  3. How can I fix it such that refreshApex consistently works?
  4. What other ways are there to clear the cache such that wire will re-fire?
  1. What on earth is going on?
  2. Am I going crazy? :o)
  3. How can I fix it such that refreshApex consistently works?
  4. What other ways are there to clear the cache such that wire will re-fire?
  1. What is going wrong?
  2. How can I fix it such that refreshApex consistently works?
  3. What other ways are there to clear the cache such that wire will re-fire?
Source Link
Robs
  • 9.4k
  • 21
  • 119
  • 224

refreshApex not always working

I have a parent LWC with a list of records and a child LWC which allows the user to perform actions on the record.

The child uses dispatchEvent and CustomEvent to notify the parent after changes have been made to the record, so that the parent can refresh the list of records.

Unfortunately, refreshApex in the parent is not always working...

Here is the code.....

parent component

<template>
  // contains a list of records, removed for brevity 
  <c-child-record-detail onback={handleBack} record-id={recordId}></c-child-record-detail>
</template>

parent JavaScript

import { LightningElement, wire } from "lwc";
import { refreshApex } from "@salesforce/apex";
import getRecords from "@salesforce/apex/MyController.getRecords";

export default class MyLWC extends LightningElement {

    records;
    wiredResult;
    records; // used to render
    recordList; // used to store the original set from the server
    filterValue = "";
    recordId;

    @wire(getRecords) wiredRecords(value) {

        this.wiredResult = value;
        const { data, error } = value;
        if (data) {
            this.error = null;
            this.recordList = data;
            this.filterList();
        } else if (error) { ... }
    }

    refreshList() {
        return refreshApex(this.wiredResult);
    }

    handleBack() {
        this.recordId = null;
        this.refreshList();
    }

    handleFilterChange(event) {
        this.filterValue = event.detail.value;
        this.filterList();
    }

    filterList() {
        switch (this.filterValue) {
            case "Status1":
                this.records = this.recordList.reduce(this.exampleReducer, []);
                break;

            // many other cases removed for brevity 
        }
    }

    exampleReducer = (accumulator, currentValue) => {
        if (currentValue.Status__c === "example") {
            accumulator.push(currentValue);
            return accumulator;
        }
        return accumulator;
    };

    // many other reducers, removed for brevity 

    handleRowClick(event) {
        this.recordId = event.currentTarget.dataset.recordId;
    }
}

I've tried very hard to reduce the code example down without losing its essence.

You will notice that I am doing client side filtering using reduce.

The c-child-record-detail component is reasonably complex, but the problem related to two buttons which are used to finish looking at the record, so we can go back to the list.

child component

child button A JavaScript

handleButtonAClick() {
    updateAsSomeSubStatus({ recordId: this.recordId}).then(result => {
        if (result === true) {
            this.backToList();
        }
    }).catch(error => this.handleError(error));
}

child button A Apex

@AuraEnabled
public static Boolean updateAsSomeSubStatus(Id recordId) {
   try {
       Opportunity record = new Opportunity(Id = recordId);
       record.Sub_Status__c = "SomeSubStatus";
       update record;
       return true;
   } catch (Exception cause) {
      throw AuraHandledExceptionFactory.create(cause);
   }
}

child button B JavaScript

handleButtonBClick() {
    updateAsStatusAndSubStatus({ recordId: this.recordId}).then(result => {
        if (result === true) {
            this.backToList();
        }
    }).catch(error => this.handleError(error));
}

child button B Apex

@AuraEnabled
public static Boolean updateAsStatusAndSubStatus(Id recordId) {
   try {
       Opportunity record = new Opportunity(Id = recordId);
       record.StageName = "SomeStageName";
       record.Sub_Status__c = null;
       update record;
       return true;
   } catch (Exception cause) {
      throw AuraHandledExceptionFactory.create(cause);
   }
}

Both buttons work, and the record is updated successfully.

Both buttons return a result of true;

Both buttons call the backToList JavaScript method

backToList() {
    this.dispatchEvent(new CustomEvent("back"));
}

The List only only refreshes correctly for button A.

I also have a refresh button on the list which calls refreshApex and no matter how many times I click on it, it does not get the refresh records.

I have to do a hard refresh of the page!

Question

  1. What on earth is going on?
  2. Am I going crazy? :o)
  3. How can I fix it such that refreshApex consistently works?
  4. What other ways are there to clear the cache such that wire will re-fire?