[SalesForce] How to delete DataTable row and corresponding record

EDIT: Scroll to the bottom of this post for the working code.

I'm very much a beginner at using SalesForce so please forgive me if this question has a trivial solution 🙁

I have a DataTable filled with movie poster information (title, inventory count). I'm just trying to make an app that adds/deletes and if I have time, edits the entries.

Right now I'm trying to get deleting working. I've tried dissecting the example at https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_datatable.htm but I'm having trouble.

Javascript controller code:

deleteTableRow : function(component, row) {
    var action = component.get("c.deletePoster");
    action.setParams({
        "toDelete": row 
    });

    $A.enqueueAction(action);
    component.refreshDataTable();
}

Here is how I refresh my DataTable (code from the JS controller):

refreshDataTable : function(component, event, helper) {
    var refreshAction = component.get("c.getPosters");
    refreshAction.setCallback(this, function(data) {
       component.set("v.Poster", data.getReturnValue()); 
    });

    $A.enqueueAction(refreshAction);
},

Apex code for deleting and refreshing/populating the table:

@AuraEnabled
public static List<Poster__c> getPosters(){    
    return [Select ID__c, Count__c, Name From Poster__c];    
}

@AuraEnabled
public static void deletePoster(Poster__c toDelete){
    delete toDelete;
}

Markup (the relevant delete code is in the 2nd lightning card):

<aura:component controller="PostroApexController" implements="flexipage:availableForRecordHome" access="global">

    <aura:attribute name="Poster" type="Poster__c"/>
    <aura:attribute name="Posters" type="List"/>
    <aura:attribute name="Columns" type="List"/>
    <aura:attribute name="newPosterTitle" type="String"/>
    <aura:attribute name="newPosterCount" type="Decimal"/>

    <aura:method name="refreshDataTable" action="{!c.refreshDataTable}" 
                 description="refreshes datatable when data changes"/>

    <aura:handler name="init" value="{!this}" action="{!c.performInit}"/>

    <div class="width200">

        <lightning:card title="Postro SalesForce Demo" iconName="standard:account" footer="Some footer">

            <p>
                Postro is an inventory management system for movie theatres, specifically relating to movie poster stock.
            </p>


            <lightning:datatable data="{! v.Poster }" columns="{! v.Columns }" keyField="ID" hideCheckboxColumn="true"
                                 onrowselection="{! c.getSelectedID}"/>        
            <hr/>        
            <lightning:input type="text" label="Poster Title" name="posterTitle" value="{!v.newPosterTitle}"/>
            <lightning:input type="number" label="Poster Count" name="posterCount" value="{!v.newPosterCount}"/>
            <lightning:button type="submit" label="Add" name="btnAdd" onclick="{! c.addNewPoster}"/>

        </lightning:card>   

        <lightning:card title="Postro Tools" footer="Some footer">

            <lightning:button type="button" label="Delete" name="btnDelete" onclick="{! c.deleteTableRow}"/>

        </lightning:card>

    </div>




</aura:component>

Here are the fields on my Poster object:
enter image description here

If I click "delete", nothing happens. How can I get this to work?


EDIT: Working code

Add new attribute to store selected rows:

<aura:attribute name="selectedRows" type="List"/>

Set DataTable's onrowselection to a JS component function to store the selected rows in the above attribute. My function is {! c.storeSelectedRows}.

Here is that function:

storeSelectedRows : function(component, event, helper){ 
    var selectedRows = event.getParam("selectedRows");
    component.set("v.selectedRows", selectedRows);
},

Finally the JS for deleting rows, set as the function for a "Delete" button. This function feels pretty hacky and could probably be made more efficient, but this works for my purposes for now:

deleteTableRows : function(component, event, helper) {

    var selectedPosters = component.get("v.selectedRows");
    var IDs = [];
    for (var i = 0; i < selectedPosters.length; i++){
        IDs[i] = selectedPosters[i].ID__c;
    }

    var action = component.get("c.deletePosterListByID");
    action.setParams({
        "idList": IDs
    });

    $A.enqueueAction(action);
    component.refreshDataTable();
}

The function to refresh is higher in this post. Thank you to everyone who helped me get here!

Best Answer

In addition to what @sfdcfox mentioned, below is how you can modify your code to work. Though the below approach will enable your code to work, but follow a more efficient approach where you don't need to make a server trip after deleting the row, instead update the dataTable values, right in the deleteTableRow function as explained in the documentation.

Declare a variable which will capture the selected row, which you will need to use in deleteTableRow JS function.

    <aura:attribute name="selectedRow" type="Object"/>

Set the value of this attribute in the getSelectedID JS function as:

component.set("v.selectedRow", selectedRows[i]); // or however you are retrieving the selectedRow

Additionally, modify your deleteRow JS function as below to align as a JS controller function for the component and use the selectedRow attribute as above:

deleteTableRow : function(component, event, helper) {
    var action = component.get("c.deletePoster");
    var row = component.get("v.selectedRow"); 
    //rest of your code
Related Topic