2

What is the recommended method of deleting a record associated with a row in a lightning:datatable? All the examples I see show to make a call to an Apex controller to do the delete (maybe I should take the hint?). However wouldn't this be a good job for force:recordData.deleteRecord?

I tried playing around with getting deletes to work but the solution I have is very awkward and doesn't quite work right. Perhaps someone has a good example of how it should be implemented with LDS?

This is what my attempt looks like:

In the cmp:

    <aura:attribute name="recordIdToDelete" description="Id of record to be deleted" type="String"/>
    <force:recordData aura:id="recordDeleter"
        recordId="{!v.recordIdToDelete}"
        fields="Id"
        targetError="{!v.recordError}"
        recordUpdated="{!c.handleDeleteRecord}" />

In the function that handles the delete button click:

    var confirmResult = confirm("Are you sure ...?");
    if (confirmResult) {                    
        cmp.set('v.recordIdToDelete', row.guestAdmissionId);
        // Need the following line in order to load the record
        cmp.find("recordDeleter").reloadRecord();
    }

The function that gets called when the record is loaded

handleDeleteRecord: function (cmp, event, helper) {

    cmp.find("recordDeleter").deleteRecord($A.getCallback(function(deleteResult) {

        if (deleteResult.state === "SUCCESS" || deleteResult.state === "DRAFT") {
            utils.showToastMessage({
                "title": "Saved",
                "message": "Record for " + row.contactName + " Deleted.",
                "type": "success"
            });
        } else if (deleteResult.state === "INCOMPLETE") {
            utils.showToastErrorMessage("User is offline, device doesn't support drafts.");
        } else if (deleteResult.state === "ERROR") {
            utils.showToastErrorMessage('Problem deleting contact, error: ' + JSON.stringify(deleteResult.error));
        } else {
            utils.showToastErrorMessage('Unknown problem, state: ' + deleteResult.state + ', error: ' + JSON.stringify(deleteResult.error));
        }
    }));
}

The problem is that after the record gets deleted the handleDeleteRecord method gets called again.

1
  • 1
    FWIW, I solved this exact issue a different way by wrapping force:recordData in an aura:if with a v.isInProgress boolean which basically creates and destroys this component just for the duration of the delete.
    – tsalb
    Commented Sep 19, 2018 at 15:50

1 Answer 1

4

Perhaps instead of binding recordId="{!v.recordIdToDelete}" you could leave it blank. And your code can do the following:

cmp.set('v.recordIdToDelete', row.guestAdmissionId);
cmp.find("recordDeleter").set("v.recordId", row.guestAdmissionId);
cmp.find("recordDeleter").reloadRecord();

At the top of handleDeleteRecord before triggering the delete, give it a way to enforce only deleting once:

var recordId = cmp.get("v.recordIdToDelete");
if (!recordId || cmp.find("recordDeleter").get("v.recordId") != recordId) 
    return;
cmp.set("v.recordIdToDelete", null);

Now even if the handler fires a second time it will not attempt to delete again.

2
  • Thanks @CharlesT, this did indeed solve my issue. Its still such an awkward contraption though.
    – Homerlex
    Commented Sep 19, 2018 at 15:47
  • Agreed it's kludgy. Maybe an alternate way to do it could be to avoid using recordUpdated handler for this. Use .reloadRecord passing in false for skipCache and a callback method. Even if this unwittingly results in double-loading the record, it guarantees the function you passed in only runs once.
    – Charles T
    Commented Sep 19, 2018 at 18:30

You must log in to answer this question.

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