[SalesForce] LWC – Lightning-Datatable Not Refreshing When Data Changes

I have a simple component that calls an apex method which returns some records. I want to display them. The problem is when I fetch the records and add them into the array, the component does not refresh. After some research I belive I need to bind "this" but since i'm new to js, i'm not sure what that means.

<template>
    <lightning-card title="Date" icon-name="standard:record">  
        <lightning-datatable columns={columns} 
                            data={data} 
                            key-field="id"
                            hide-checkbox-column="true"
                            show-row-number-column="true"></lightning-datatable>
    </lightning-card>
</template>

Js:

import { LightningElement,api, track, wire } from 'lwc';
import populateData from '@salesforce/apex/ApexClass.Data';

export default class RelatedListEventOrder extends LightningElement {
    @api recordId;
    @track columns = [
        {
            label: 'Account Name',
            fieldName: 'accountname', 
            type: 'text',
        }, {
            label: 'Status',
            fieldName: 'Status',
            type: 'text'
        }, {
            label: 'Delivered',
            fieldName: 'delivered',
            type: 'boolean'
        }
    ];

    error;
    @track data = [
        {
            accountname: 'a',
            delivered: true,
            status: 'good'
        } 
    ];
    
    connectedCallback() {
        window.console.log("In connectedCallback");
        this.eventOrders();
    }

    eventOrders() {
        window.console.log("this.recordId: " + this.recordId);
        populateData({ recordId: this.recordId })
            .then((resWrapper) => {
                window.console.log("Sucessful");
                window.console.log("resWrapper: " + resWrapper);
                if(resWrapper){
                    window.console.log("resWrapper length: " + resWrapper.length);
                    resWrapper.forEach((res) => {
                        window.console.log("res.order.Account.Name: " + res.order.Account.Name);
                        window.console.log("res.order.Delivered__c: " + res.order.Delivered__c);
                        
                        window.console.log("res.order.Status: " + res.order.Status);

                        let lineItem = {};
                        lineItem.accountname = res.order.Account.Name,
                        lineItem.delivered = res.order.Delivered__c,
                        lineItem.status = res.order.Status,
                        window.console.log("========lineItem acc name:====== " +lineItem.accountname);
                        this.data.push(lineItem);
                    });
                }
                window.console.log("data.length: " + this.data.length);
            })
            .catch((error) => {
                this.error = error;
                window.console.log("Error: " + error);
            });
    }

}

The records return fine from apex as I can view then in the console. And lineItem is also populated. My question is when I add them to data, why is the component not reflecting this change? I have a feeling it is because "this" is not set correctly but I am unsure how to fix.

Best Answer

LWC data binding doesn't detect a call to push.

make an intermediate variable, and push to that array, then assign it to the data array right at the end. eg:

let temp = [];
temp.push(lineItem);
//ect ect
this.data = temp;