0

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);
    }
3
  • You don't really need the wiredMetricsResult variable. Replace wiredMetrics(result) { with wiredMetrics({error, data}) { and then you can set your variable with just this.data. then try calling refreshApex(this.data) instead – stackasaur Mar 30 '20 at 18:24
  • @stackasaur Thanks - The refresh still isn't working though. – nfoley Mar 30 '20 at 18:42
  • Try adding .catch(error => {console.log(error);}); to the end of the refreshApex() call to see if it's failing for any reason. – stackasaur Mar 30 '20 at 18:52
0

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
    }

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.