[SalesForce] How to get lwc record-edit-form onsubmit to refresh the entire component

I have a component with 1) a datatable of Metric__c records, and 2) a record-edit-form to add a new metric record. The Submit button on the form successfully creates the new record, but because the whole component doesn't refresh, the record doesn't appear in the datatable unless you manually refresh the page. How can I make the form's {handleSubmit} action refresh the datatable/whole component?

HTML:

<template>
    <lightning-card 
        title="Metrics:"
        icon-name="standard:metrics">
    <div class="slds-m-top_medium slds-m-bottom_medium">

        <template if:true={data}>
        <!-- Table -->
            <div>
                <lightning-datatable
                        key-field={id}
                        data={data}
                        columns={columns}
                        onsave={handleSave}
                        draft-values={draftvalues}
                        hide-checkbox-column="true">
                </lightning-datatable>
            </div>
        </template>

        <template if:false={data}>
            <center><p>No metrics for this responsibility yet.</p></center>
        </template>

        <!--Add Metric button. Hidden if layout to add new metric is showing-->    
        <template if:false={showForm}>
            <div>
            <center> <lightning-button label="Add Metric" title="Add Metric" 
                        icon-name="utility:add" icon-position="left" 
                        onclick={addMetric}> </lightning-button> </center>
            </div>
        </template>

        <!--Show layout to add a new metric if the Add Metric button is clicked-->
        <template if:true={showForm}>
            <div class="slds-m-around_medium">
            <lightning-record-edit-form object-api-name="Metric__c" onsuccess={handleSuccess}>
                <lightning-input-field field-name="Responsibility__c" value={recordId} disabled></lightning-input-field>
                <lightning-input-field field-name="Name"></lightning-input-field>
                <lightning-input-field field-name="Minimum__c"></lightning-input-field>
                <lightning-input-field field-name="Expected__c"></lightning-input-field>
                <lightning-button class="slds-m-top_small"
                                  type="reset"
                                  label="Cancel"
                                  onclick={handleCancel}>
                </lightning-button>
                <lightning-button class="slds-m-top_small"
                                  type="submit"
                                  label="Submit"
                                  onclick={handleSubmit}>
                </lightning-button>
            </lightning-record-edit-form>
            </div>
        </template>

        <template if:true={error}>
            <p>Data Error</p>
        </template>

    </div>
    </lightning-card>
</template>

Here's what I currently have for my JS:

import { LightningElement, api, track, wire } from 'lwc';
import { createRecord } from 'lightning/uiRecordApi';
import { updateRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import getMetrics from '@salesforce/apex/AORMetricsController.getMetrics';


export default class MetricsList extends LightningElement {
    @api recordId   //this is the Responsibility Id when placed on a record page, or passed in from a parent component
    @track data;
    @track columns = [     //columns for datatable
        { label: 'Metric', fieldName: 'Name', editable: true, wrapText: true },
        { label: 'Minimum', fieldName: 'Minimum__c', type: 'number', cellAttributes: { alignment: 'left' }, editable: true} ,
        { label: 'Expected', fieldName: 'Expected__c', type: 'number', cellAttributes: { alignment: 'left' }, editable: true },
        { label: 'Currently Being Measured?', fieldName: 'Currently_Being_Measured__c' },
    ];
    @track draftValues = [];    //field values from inline edit before they're saved into the database
    @track showForm = false;    //if True, the component displays the form to add a new metric
    @track error;

    wiredMetricsResult;
    recordId = this.recordId

    @wire(getMetrics, {resId: '$recordId'})
        wiredMetrics(result) {
            this.wiredMetricsResult = result;
            if (result.data) {
                this.data = result.data;
                this.error = undefined;
            } else if (result.error) {
                this.data = undefined;
                this.error = result.error;
            }
        }
    KEYFIELD = 'Id';

    addMetric() {
        this.showForm = true
    }
    handleCancel() {
        this.showForm = false;
    }
    handleSubmit(event) {     
        event.preventDefault();
        const fields = event.detail.fields;
        createRecord({Metric__c, fields})
            .then(() => {return refreshApex(this.wiredMetricsResult);
            });
        this.showForm = false;
    }
    handleSuccess(event) {
        console.log('Record Id ' + event.detail.id);
        const evt = new ShowToastEvent({
            title: "Metric created",
            message: "The new metric has been added.",
            variant: "success"
        });
        this.showForm = false;
    }
}

Update: refreshApex() works if it's called independently. I added a "Refresh" button in the html where onclick = {handleRefresh}, and added the following in JS. Would still like this to happen automatically when handleSubmit() is called, rather than manually clicking a separate button to refresh.

    handleRefresh() {                   
        return refreshApex(this.wiredMetricsResult);
    }

Best Answer

As onsucess is being called in your code, adding refresh component in onsucess function would definitely work. Calling the refresh component onsubmit would be too early and would not provide you exact results.

handleSuccess(event) {
        console.log('Record Id ' + event.detail.id);
        const evt = new ShowToastEvent({
            title: "Metric created",
            message: "The new metric has been added.",
            variant: "success"
        });
        this.showForm = false;
        return refreshApex(this.wiredMetricsResult);//Add it here
    }
Related Topic