1

Below is just an example to showcase what I am trying to solve. I have data table that displays accounts with Active__c = 'No'. I can select the records and click Activate Account to make Active__c = 'Yes' for those accounts.

The problem - once the server call updates the account and returns back the data in data table needs to be refreshed to show the update. However, the state of the table doesn't change and the selected rows remain as it is.

What I have tried - I tried using refreshApex thinking it will refresh the view but was not successful. Below is the code:

HTML:

<template>
    <lightning-card class="slds-p-left--medium">
        <div class="slds-grid">
                <div style="height: 300px;">
                    <lightning-datatable
                            key-field="id"
                            data={apexData}
                            columns={columns}
                            onrowselection={getSelectedName}
                            selected-rows={selectedRows}>
                    </lightning-datatable>
                </div> 
        </div>
    </lightning-card>
    <div>
        <lightning-button label="Activate Account" title="Activate Account" onclick={handleActivate}> </lightning-button>
    </div>
</template>

JS:

import { LightningElement, api, wire } from 'lwc';
import getApexData from '@salesforce/apex/BodyTableController.getData';
import makeAccountActive from '@salesforce/apex/BodyTableController.makeAccountActive';
import { refreshApex } from '@salesforce/apex';

const columns = [
    { label: 'Name', fieldName: 'name' },
    { label: 'AccountNumber', fieldName: 'accNum'},
];

export default class BodyTableComponent extends LightningElement {
    apexData;
    columns = columns;
    error;

    setOfIds = new Set();
    selectedRows = [];
    @api pageNumber = 0;

    @wire(getApexData, { pageNumber: '$pageNumber' })
    wiredInfo({ error, data }) {
        if (data) {
            this.apexData = data;
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.apexData = undefined;
        }
    }

    getSelectedName(event) {
        const selectedRows = event.detail.selectedRows;
        console.log('selectedRows --> ' + JSON.stringify(selectedRows));
        for (let i = 0; i < selectedRows.length; i++){
            this.setOfIds.add(selectedRows[i].id);
        }        
    }

    handleActivate(){
        if(this.setOfIds.size > 0 ){
            let recIdList =  Array.from(this.setOfIds);
            makeAccountActive({accIds: recIdList })
                .then((result) => {
                    if(result){
                        // Need to refresh the view again
                        refreshApex(this.apexData)
                    }
                    this.error = undefined;
                })
                .catch((error) => {
                    this.error = error;
                });
        }
    }

}

Apex Controller:

public with sharing class BodyTableController {

    public class BodyTableWrapper{ 
        @AuraEnabled
        public String id; 
        @AuraEnabled
        public String name; 
        @AuraEnabled 
        public String accNum; 
    }

    @AuraEnabled(cacheable=true)
    public static List<BodyTableWrapper> getData(Integer pageNumber){
        List<BodyTableWrapper> wrpList = new List<BodyTableWrapper>();

        for(Account acc : [SELECT Id,Name,AccountNumber FROM Account WHERE Active__c = 'No' LIMIT 10]){
            BodyTableWrapper wrpObj = new BodyTableWrapper();
            wrpObj.id = acc.Id;
            wrpObj.name = acc.Name;
            wrpObj.accNum = acc.AccountNumber;
            wrpList.add(wrpObj);
        }
        return wrpList;
    }


    @AuraEnabled
    public static Boolean makeAccountActive(List<Id> accIds){
        Boolean result = false;
        List<Account> accToActivate = new List<Account>();
        if(accIds!= null && !accIds.isEmpty()){
            for(Id accId : accIds){
                accToActivate.add(new Account(Id=accId, Active__c='Yes'));
            }
        }
        if(!accToActivate.isEmpty()){
            update accToActivate;
            result = true;
        }
        return result;
    }

}
3
  • And maybe you can call getRecordNotifyChange([{recordId: this.recordId}]); developer.salesforce.com/docs/component-library/documentation/… after update Apex call. – itzmukeshy7 Feb 18 at 14:30
  • 1
    I guess I can't add this as I am not using the LDS cache in my example. In the link you provided check this NOTE If you’re using an @wire to get record data via an Apex method, simply call refreshApex(), which uses the configuration bound to the @wire to get the data and update the cache. – SfdcBat Feb 18 at 14:40
  • Yes, you are right, we don't need to do that when using @wire. – itzmukeshy7 Feb 18 at 16:35
1

Refresh apex needs to be called on wiredProperty itself, not data.

@wire(getApexData, { pageNumber: '$pageNumber' })
wiredInfo(value) {
    this.wiredApexData = value;
    if (value.data) {
        this.apexData = value.data;
        this.error = undefined;
    } else if (value.error) {
    }
}

now call refresh apex on wiredApexData.

refreshApex(this.wiredApexData);
5
  • I declared a new class variable - wiredApexData and did like above example. However I get an error on the page - Error during LWC component connect phase: [LWC component's @wire target property or method threw an error during value provisioning. Original error: [Cannot destructure property 'error' of 'e' as it is undefined.]] – SfdcBat Feb 18 at 14:33
  • @SfdcBat can you try the updated code? Also please define another property as wiredApexData – Rahul Gawale Feb 18 at 15:24
  • tried that , and got this error - [Cannot destructure property 'data' of 'e' as it is undefined.]] – SfdcBat Feb 18 at 18:27
  • 1
    Ok , found the issue. I had to use it like this - wiredInfo(result) { this.wiredApexData = result; – SfdcBat Feb 18 at 18:37
  • 1
    @SfdcBat ahh. strange this was used to work before anyway, I am glad that your issue is resolved. – Rahul Gawale Feb 19 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.