[SalesForce] refresh lightning-datatable after save

I'm using lightning-record-edit-form to update a record. I want my lightning-datatable to reflect the changes. I have to refresh the page to see the change in the lightning-datatable. Is there an easy way to achieve a refresh of the lightning-datatable? or am I doing something fundamentally wrong? I've searched through many possible solutions with no luck. Thanks in advance for any guidance.

HTML:

<template>
    <template if:false={staffingAssignmentSelected}>
        <lightning-card title="Staffing Assignments" icon-name="custom:custom18">
            <div class="card">
                <template if:false={gotData}>
                    <div class="slds-p-around--medium">
                        <div class="slds-text-heading--small">Determining available Staffing Assignments...</div>
                    </div>
                </template>

                <template if:true={hasNoStaffingAssignments}>
                    <div class="slds-p-around--medium slds-text-heading--small">No Staffing Assignments are available.</div>
                </template>
                <template if:true={hasStaffingAssignments}>
                    <lightning-datatable
                            data={datatableStaffingAssignments}
                            columns={staffingAssignmentColumns}
                            key-field="Id"
                            onrowselection={handleRowSelection}
                            selected-rows={selectedStaffingAssignmentIds}>
                    </lightning-datatable>
                </template>
            </div>
        </lightning-card>
    </template>
    <template if:true={staffingAssignmentSelected}>
        <lightning-card title="Update Staffing Assignment" icon-name="custom:custom18">
            <lightning-record-edit-form record-id={staffingAssignmentId} object-api-name="Staffing_Assignment__c" onsuccess={resetStaffingSelection}>
                <lightning-input-field field-name="Title__c"></lightning-input-field>
                <lightning-input-field field-name="User__c"></lightning-input-field>
                <lightning-button label="Save" type="submit" name="Save" variant="brand"></lightning-button>&nbsp;
                <lightning-button label="Cancel" type="cancel" name="Cancel" onclick={resetStaffingSelection} variant="brand"></lightning-button>
            </lightning-record-edit-form>
        </lightning-card>
    </template>

</template>

JavaScript:

import {LightningElement, wire, track, api} from 'lwc';
import getStaffingAssignmentByParentId from '@salesforce/apex/StaffingAssignment.getStaffingAssignmentByParentId';
import { refreshApex } from '@salesforce/apex';

const staffingAssignmentColumns = [
    {label: 'Title', fieldName: 'Title__c', type: 'pickList'},
    {label: 'User', fieldName: 'UserName', type: 'text'}
];

//{label: 'UserId', fieldName: 'User__c', type: 'sObject'},

export default class StaffingAssignment extends LightningElement {
    @api recordId;  //The Petition record Id.
    @track datatableStaffingAssignments;
    @track staffingAssignments = [];  //All available staffingAssignments
    @api selectedStaffingAssignments = [];
    @track staffingAssignmentColumns = staffingAssignmentColumns;
    @track error;
    @track selectedStaffingAssignmentIds = [];
    @track gotData = false;

    get hasNoStaffingAssignments() {
        if (this.gotData) {
            if (this.datatableStaffingAssignments && this.datatableStaffingAssignments.length ==  0) {
                return true;
            }
        }
        return false;
    }

    get hasStaffingAssignments() {
        if (this.gotData) {
            if (this.datatableStaffingAssignments && this.datatableStaffingAssignments.length > 0) {
                return true;
            }
        }
        return false;
    }

    connectedCallback() {

        getStaffingAssignmentByParentId({parentId: this.recordId})
            .then(result => {
                console.log(JSON.stringify(result));
                let rows = result;
                let rowBuilder = [];
                for (let i = 0; i < rows.length; i++) {
                    let row = rows[i];
                    //Datatable can't handle related fields, so flatten the data
                    if (row.User__r) {
                        if (row.User__r.Name) {
                            //Add the User Name to the first level of the row
                            let pair = {UserName: row.User__r.Name};
                            row = {...row, ...pair};
                        }
                    }
                    rowBuilder.push(row);
                }

                this.datatableStaffingAssignments = rowBuilder;
                this.gotData = true;
                this.error = undefined;
            })
            .catch(error => {
                //this.error = reduceErrors(error).join(', ');
                this.record = undefined;
            });
    }

    resetStaffingSelection() {
        this.selectedStaffingAssignmentIds = [];
    }

    handleRowSelection(event) {
        const selectedRows = event.detail.selectedRows;
        this.selectedStaffingAssignmentIds = [];

        for (let i = 0; i < selectedRows.length; i++) {
            this.selectedStaffingAssignmentIds.push(selectedRows[i].Id);
        }
    }
    get staffingAssignmentSelected() {
        if (this.selectedStaffingAssignmentIds != null && this.selectedStaffingAssignmentIds.length > 0) {
            return true;
        }
        return false;
    }
    get staffingAssignmentId () {
        if (this.selectedStaffingAssignmentIds) {
            return this.selectedStaffingAssignmentIds[0];
        }
    }
}

Best Answer

The way you have it built you would need to update your success handler to refetch records after they have been updated.

.html

<lightning-record-edit-form onsuccess={handleSuccess}>

.js

connectedCallback() {
    this.fetchStaffingAssignments();
}

handleSuccess() {
    this.resetStaffingSelection();
    this.fetchStaffingAssignments();
}

fetchStaffingAssignments(){

    getStaffingAssignmentByParentId({parentId: this.recordId})
    .then(result => {
        console.log(JSON.stringify(result));
        let rows = result;
        let rowBuilder = [];
        for (let i = 0; i < rows.length; i++) {
            let row = rows[i];
            //Datatable can't handle related fields, so flatten the data
            if (row.User__r) {
                if (row.User__r.Name) {
                    //Add the User Name to the first level of the row
                    let pair = {UserName: row.User__r.Name};
                    row = {...row, ...pair};
                }
            }
            rowBuilder.push(row);
        }

        this.datatableStaffingAssignments = rowBuilder;
        this.gotData = true;
        this.error = undefined;
    })
    .catch(error => {
        //this.error = reduceErrors(error).join(', ');
        this.record = undefined;
    });

}