2

I am using a util lwc data table and passing list of records from the parent component, I am using a refresh button to re-fetch the records from Apex (imperatively) and update the LWC data table but the LWC data table is not updating records in data table.

Util LWC Data table Template :

<div class="slds-grid slds-grid_vertical-align-center slds-grid_align-spread slds-scrollable_x"> 
            <div class="slds-col slds-scrollable_x" style={tablewidth} >
                    <lightning-datatable
                        key-field="Id"
                        columns={columns}
                        data={recordsToDisplay}
                        hide-checkbox-column
                        default-sort-direction={defaultSortDirection}
                        sorted-direction={sortDirection}
                        sorted-by={sortedBy}
                        onsort={onHandleSort}
                        onrowaction={handleRowAction}
                        class="slds-table_header-fixed_container slds-table_bordered slds-table_col-bordered slds-border_top "
                        >
                </lightning-datatable>            
            </div>
        </div>

Button on Child Util LWC data table :

<lightning-button  title="refresh records" icon-name="utility:refresh" icon-position="center" onclick={handleRefresh} class="slds-m-left_x-small"></lightning-button>

Child Data table JS :

handleRefresh(event){
    this.dispatchEvent( new CustomEvent('refreshrecords', {detail:event.detail}));
}

Parent HTML :

<c-util-lwc-datatable 
            columns={ordercolumns}
            records={allorders}
            onactionclicked={handleselectedorder}
            show-search-box={showsearchbox}
            total-records={totalRecords}
            onrefreshrecords={handlerefreshrecords}
            >
</c-util-lwc-datatable>

JS :

handlerefreshrecords(event){
    this.handleGetOrders();
}

handleGetOrders(){
    getAllOrders({accountId: this.recordId})
    .then((result) =>{
        this.allorders = result.map(row=>{
            return{...row, opportunityName: '/' + row.Id, Orders: row.Order_Id__c}
        });
    })
    .catch((error) => {
        this.error = error;
        this.allorders = undefined;     
    })
}

Even though this.allorders is coming back with new data, Child LWC data table is not being update with new data. I do not have a @wire method to use refreshApex.

How can I make sure the child LWC gets new data and data table renders with new data?

11
  • @CasparHarmer can you give an example how? Because I am not using a for:each, how would I add key and how can I use it? May 10, 2021 at 20:51
  • @CasparHarmer I am not using forEach here, it's only Data table where I am using a Key but it doesnt seem to work. On the side, I am trying it to see if I can use Wire method. May 10, 2021 at 21:08
  • is getAllOrders apex method cacheable?
    – glls
    May 10, 2021 at 21:09
  • @glls no, it is not. When I log the new order response, I do get updated orders list, just the LWC is not re-rendering with new values. May 10, 2021 at 21:10
  • what does your c-util-lwc-datatable template look like?
    – glls
    May 10, 2021 at 21:11

2 Answers 2

0

I built and tested my own version that I have verified to work (on Accounts)

Child HTML:

<template>
  <lightning-button  title="refresh records" icon-name="utility:refresh" icon-position="center" onclick={handleRefresh} class="slds-m-left_x-small"></lightning-button>

  <div class="slds-grid slds-grid_vertical-align-center slds-grid_align-spread slds-scrollable_x"> 
    <div class="slds-col slds-scrollable_x" >
        <lightning-datatable
                key-field="Id"
                columns={columns}
                data={records}
                class="slds-table_header-fixed_container slds-table_bordered slds-table_col-bordered slds-border_top ">
        </lightning-datatable>            
    </div>
</div>
</template>

Child JS:

import { LightningElement, api, track } from 'lwc';

const COLUMNS = [
  { label: 'Name', fieldName: 'Name' },
  { label: 'Website', fieldName: 'Website', type: 'url' },
  { label: 'Phone', fieldName: 'Phone', type: 'phone' }
];

export default class LwcTestTable extends LightningElement {

  columns = COLUMNS;
  @api records;

  handleRefresh(event){
    this.dispatchEvent( new CustomEvent('refreshrecords', {detail:event.detail}));
  }

}

Parent HTML:

<template>
    <lightning-card  >
        <c-lwc-test-table
            records={allaccounts}
            onrefreshrecords={handlerefreshrecords} >
        </c-lwc-test-table>
    </lightning-card>
</template>

Parent JS:

import { LightningElement,track } from 'lwc';
import getAccounts from "@salesforce/apex/TestClass.getAccounts";

export default class LwcTester extends LightningElement {

  @track allaccounts = []

  connectedCallback(){
    this.handleGetAccounts();
  }

  handlerefreshrecords(event) {
    this.handleGetAccounts();
  }

  handleGetAccounts() {
    getAccounts({})
      .then((result) => {
        this.allaccounts = result.map(row => {return { ...row }});
      })
      .catch((error) => {this.allaccounts = undefined;})
  }
}
7
  • I already have a key field in the Util LWC Data table set as Id, the line return I have is only to add a hyperlink for Opportunity Name in the data table. how do I add Id and which ID should it be? May 10, 2021 at 20:57
  • I am extending lightning-data-table, that is what my util is and I have key-field="Id" in my util lwc. So that in the return, I just set row.Id for every row (allOrders), but that is not refreshing the lwc. May 10, 2021 at 21:02
  • plus, I dont really have for-each here. May 10, 2021 at 21:02
  • I literally have same one, it's still not working, no idea why. May 11, 2021 at 1:09
  • Try testing in Aura - make an aura app and include this component and run in the dev console. That's how I ran mine. At least you'd know then that it was limited to some profile/sharing/permissions thing. May 11, 2021 at 1:11
0

Try to use getter for the orders, now it should work fine. One time I also face something similar so it worked for me by using getter because getters being called on the change of data everytime and it will also create the new reference so it will work

@track orders = [];
 handlerefreshrecords(event){
        this.handleGetOrders();
    }
    
handleGetOrders(){
    getAllOrders({accountId: this.recordId})
    .then((result) =>{
        this.orders = result.map(row=>{
            return{...row, opportunityName: '/' + row.Id, Orders: row.Order_Id__c}
        });
    })
    .catch((error) => {
        this.error = error;
        this.allorders = undefined;     
    })
}

get allorders (){
    return [...this.orders];
}

You must log in to answer this question.

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