3

I am working on an LWC datatable application in which I must call an Apex method imperatively, passing it the JSON string of the event.detail.draftValues which it uses to add or update some Sobject records. All of that works fine. The problem is that, after my javascript "Save" function, I want to clear all of those "old" draft values, so my users can start editing fields again without having to refresh the page; but I cannot figure out how to do that. That is, remove the yellow highlighting as shown below.

draftvalue highlight

So if they press "Save" again, the previously selected values are again sent to the Apex method, which is not optimal. I am trying to execute the refreshApex() function, but it must not be working. The relevant JS and HTML are shown. I would be grateful if anybody could assist me, and I apologize if I have not used this forum correctly, as it is my first time posting.

import { LightningElement, wire, track } from 'lwc';
import getPriceRecords from '@salesforce/apex/FikeStdPriceBookController.getPriceRecords';
import updatePriceRecords from '@salesforce/apex/FikeStdPriceBookController.updatePriceRecords';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class StdPriceBookWorkBench extends LightningElement {

    @track productCategorySearchKey = '';
    @track productFamilySearchKey = '';
    @track productLineSearchKey = '';
    @track productSubLineSearchKey = '';
    @track productSearchKey = '';
    @track productDescriptionSearchKey = '';
    @track error;
    @track pricesList;

    @wire(
        getPriceRecords, 
        {
            productCategorySearchKey: '$productCategorySearchKey', 
            productFamilySearchKey: '$productFamilySearchKey',
            productLineSearchKey: '$productLineSearchKey',
            productSubLineSearchKey: '$productSubLineSearchKey',
            productSearchKey: '$productSearchKey',
            productDescriptionSearchKey: '$productDescriptionSearchKey'
        }
    )
    wiredTargets({ error, data }) {
        if (data) {
            this.pricesList = data;  
        } else if (error) {
            this.error = error;
        }
    }

    // This is the standard handleSave function, in which I think the problem is to be found.
    handleSave(event) {
        var draftValuesStr = JSON.stringify(event.detail.draftValues);
        updatePriceRecords({updateObjStr: draftValuesStr}).then(result => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                    message: result + ' price records have been added or updated.',
                    variant: 'success'   
                })
            );  // End of dispatchEvent
            this.draftValues = [];
            refreshApex(this.getPriceRecords);
        }).catch(error => {
            // Handle error
        });
    }
}

Here is the datatable in my HTML File:

<template if:true={pricesList}>        
    <lightning-datatable 
        data={pricesList} 
        columns={columns} 
        key-field="Id"
        onsave={handleSave}
        hide-checkbox-column="true"
        draft-values={draftValues}
    ></lightning-datatable>   
</template>
<template if:true={error}>
    {error}
</template>

3 Answers 3

6

I have had success with clearing the draft values on the lightning-datatable by directly editing the draftValues property on the lightning-datatable DOM element. This seems to remove the Save and Cancel buttons and clear the yellow highlighting from the cells you edited:

this.template.querySelector("lightning-datatable").draftValues = [];
1

You should be calling the refresh apex on the value provisioned by the wire service and not on the apex method itself. Update your wire service call as follows

@wire(getPriceRecords, {
    productCategorySearchKey: '$productCategorySearchKey', 
    productFamilySearchKey: '$productFamilySearchKey',
    productLineSearchKey: '$productLineSearchKey',
    productSubLineSearchKey: '$productSubLineSearchKey',
    productSearchKey: '$productSearchKey',
    productDescriptionSearchKey: '$productDescriptionSearchKey'
})
wiredTargets(value) {
    // Hold on to the provisioned value so we can refresh it later.
    this.wireResult = value; // track the provisioned value
    const { data, error } = value; // destructure the provisioned value
    
    if (data) {
        this.pricesList = data;  

    } else if (error) {
        this.error = error;
    }
}

and update your refresh apex call as follows:

refreshApex(this.wireResult);

This should call the apex method again and fetch new values into this.pricesList which will refresh the data table. At a high level, rest of the code looks fine.

1
  • Thanks so much for this information. I did what you suggested and it now works perfectly. Sep 7, 2020 at 14:45
0

Right inside your save method you can access the event's target (table) and reset the value right there:

handleSave(event) {
  var draftValuesStr = JSON.stringify(event.detail.draftValues);
  event.target.draftValues = [];
}

You must log in to answer this question.

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