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
    Sep 19 '18 at 15:50
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
    Sep 19 '18 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
    Sep 19 '18 at 18:30

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.