[SalesForce] Multi Delete Lightning DataTable Using Checkbox

I was Experimenting with lightning:datatable, trying to delete multiple records using checkbox.
Component:-

<aura:component controller="DatatableController" implements="flexipage:availableForAllPageTypes,force:appHostable">

    <!--Declare Attributes-->
    <aura:attribute name="data" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    <aura:attribute name="selectedRowsCount" type="Integer" default="0"/>
    <aura:attribute name="selectedRowsDetails" type="Object" />
    <aura:attribute name="selectedRowsList" type="List" />
    <aura:attribute name="maxRowSelection" type="Integer" default="10"/>
    <aura:attribute name="selectedRows" type="List" />
    <aura:attribute name="enableInfiniteLoading" type="Boolean" default="true"/>
    <aura:attribute name="initialRows" type="Integer" default="10"/>
    <aura:attribute name="rowsToLoad" type="Integer" default="10"/>
    <aura:attribute name="totalNumberOfRows" type="Integer" default="10"/>
    <aura:attribute name="loadMoreStatus" type="String" default="Please scroll down to load more data"/>
    <aura:attribute name="showRowNumberColumn" type="Boolean" default="false"/>
    <aura:attribute name="rowNumberOffset" type="Integer" default="0"/>
    <aura:attribute name="rowsToAdd" type="Integer" default="10"/>
    <aura:attribute name="currentCount" type="Integer" default="10"/>
    <aura:attribute name="sortedBy" type="String"/>
    <aura:attribute name="sortedDirection" type="String"/>
    <aura:attribute name="defaultSortDirection" type="String"/>

    <!--Declare Handlers-->
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <!--Component Start-->
    <div class="slds-m-around_xx-large" style="height: 300px">
        <lightning:datatable columns="{!v.columns}"
                             data="{!v.data}"
                             keyField="Id"
                             showRowNumberColumn="true"
                             rowNumberOffset="0"
                             onrowaction="{!c.handleRowAction}"
                             selectedRows="{!v.selectedRows}"
                             maxRowSelection="{!v.maxRowSelection}"
                             onrowselection="{!c.handleSelectedRow}"
                             enableInfiniteLoading="true"
                             loadMoreOffset="{!v.loadMoreOffset}"
                             sortedBy="{!v.sortedBy}"
                             sortedDirection="{!v.sortedDirection}"
                             defaultSortDirection="{!v.defaultSortDirection }"
                             onsort="{!c.handleColumnSorting}"
                             onloadmore="{!c.handleLoadMoreContacts}"/>
        <br/>
        <div class="slds-float_left">
            <strong>Total Rows : {!v.totalNumberOfRows}</strong>
            &nbsp;&nbsp;
            <strong>Selected Rows: {!v.selectedRowsCount }</strong>
        </div>
        <div class="slds-float_right">
            <strong>{!v.loadMoreStatus}</strong>
        </div>
        <br/>
        <br/>
        <div class="slds-float_left">
            <lightning:button label="Delete Selected Contacts"  variant="brand" onclick="{!c.deleteSelectedRows}"/>    
        </div>
    </div>
    <!--Component End-->
</aura:component>

Controller.js:-

   ({
    doInit : function(component, event, helper) {
        helper.getTotalNumberOfContacts(component);
        helper.getColumnAndAction(component);
        helper.getContacts(component);
    },

    handleLoadMoreContacts: function (component, event, helper) {
        event.getSource().set("v.isLoading", true);
        component.set('v.loadMoreStatus', 'Loading....');
        helper.getMoreContacts(component, component.get('v.rowsToLoad')).then($A.getCallback(function (data) {
            if (component.get('v.data').length == component.get('v.totalNumberOfRows')) {
                component.set('v.enableInfiniteLoading', false);
                component.set('v.loadMoreStatus', 'No more data to load');
            } else {
                var currentData = component.get('v.data');
                var newData = currentData.concat(data);
                component.set('v.data', newData);
                component.set('v.loadMoreStatus', 'Please scroll down to load more data');
            }
            event.getSource().set("v.isLoading", false);
        }));
    },

    handleSelectedRows: function (component, event, helper) {
        var data = component.get('v.data');
        var selectedRowList =  component.get("v.selectedRowsList");
        console.log('selectedRowList-' + selectedRowList);
    },

    handleSelectedRow: function(component, event, helper){
        var selectedRows = event.getParam('selectedRows');
        component.set("v.selectedRowsCount", selectedRows.length);
        let obj =[] ; 
        for (var i = 0; i < selectedRows.length; i++){
            obj.push({Name:selectedRows[i].Name});
        }
        component.set("v.selectedRowsDetails", JSON.stringify(obj) );
        component.set("v.selectedRowsList", event.getParam('selectedRows'));
    },

    handleRowAction: function (component, event, helper) {
        var action = event.getParam('action');
        switch (action.name) {
            case 'new':
                helper.createContactRecord(component, event);
                break;
            case 'edit':
                helper.editContactRecord(component, event);
                break;
            case 'delete':
                helper.deleteContactRecord(component, event);
                break;
            case 'view':
                helper.viewContactRecord(component, event);
                break;
        }
    },

    handleColumnSorting: function (component, event, helper) {
        var fieldName = event.getParam('fieldName');
        var sortDirection = event.getParam('sortDirection');
        component.set("v.sortedBy", fieldName);
        component.set("v.sortedDirection", sortDirection);
        helper.sortData(component, fieldName, sortDirection);
    },

    deleteSelectedRows: function (component, event, helper) {
        var selectedRows = component.get('v.selectedRows');
        var selectedIds = [];
        for (var i = 0; i < selectedRows.length; i++) {
            selectedIds.push(selectedRows[i].Id);
        }
         helper.deleteSelectedHelper(component, event, selectedIds);
    },
})

Helper:-

deleteSelectedHelper: function(component, event, selectedIds) {

    var action = component.get( 'c.deleteRecords' );
    action.setParams({
        "lstRecordId": selectedIds,
    });
    console.log("****Id****",selectedIds);
    action.setCallback(this, function(response) {           
        // Getting the state from response
        var state = response.getState();
        if(state === 'SUCCESS') {
            // Getting the response from server
            var dataMap = response.getReturnValue();
            // Checking if the status is success
            if(dataMap.status=='success') {
                // Setting the success toast which is dismissable ( vanish on timeout or on clicking X button )
                toastEvent.setParams({
                    'title': 'Success!',
                    'type': 'success',
                    'mode': 'dismissable',
                    'message': dataMap.message
                });
                // Fire success toast event ( Show toast )
                toastEvent.fire();            
                window.location.reload();
            }
            // Checking if the status is error 
            else if(dataMap.status=='error') {
                // Setting the error toast which is dismissable ( vanish on timeout or on clicking X button )
                toastEvent.setParams({
                    'title': 'Error!',
                    'type': 'error',
                    'mode': 'dismissable',
                    'message': dataMap.message
                });
                // Fire error toast event ( Show toast )
                toastEvent.fire();                
            }
        } else {
            // Show an alert if the state is incomplete or error
            alert('Error in getting data');
        }
        //this.onLoad(component, event);
    });
    $A.enqueueAction(action);

Server Side Controller:-

@AuraEnabled
    public static List < String > deleteRecords(List < String > lstRecordId) {
        // for store Error Messages  
        List < String > oErrorMsg = new List < String > ();
        // Query Records for delete where id in lstRecordId [which is pass from client side controller] 
        List < Contact > lstDeleteRec = [select Id from contact where id IN: lstRecordId];
        Database.DeleteResult[] DR_Dels = Database.delete(lstDeleteRec, false);
        // Iterate through each returned result
        for (Database.DeleteResult dr: DR_Dels) {
            if (dr.isSuccess()) {
                system.debug('successfully deleted');
                // Operation was successful
            } else {
                // Operation failed, so get all errors   
                oErrorMsg.add('');
                for (Database.Error err: dr.getErrors()) {
                    // add Error message to oErrorMsg list and return the list
                    oErrorMsg.add(err.getStatusCode() + ': ' + err.getMessage());
                }
            }
        }
        return oErrorMsg;

    }

My Question is how to get the Record Id's of Selected Rows and store those in a list in controller.js? Currently That array is returning null.
Could Someone Fill in the Logic and Explain?
Thanks!!

This is the Debug from Lightning Inspector

Best Answer

Your v.selectedRows attribute should be automatically populated with the subset of the v.data row objects that are selected. So loop over the v.selectedRows collection and pick out the Id attribute of each adding it to an array.

Example:

var selectedRows = component.get('v.selectedRows');
var selectedIds = [];
for (var i = 0; i < selectedRows.length; i++) {
    selectedIds.push(selectedRows[i].Id);
}

and then:

    action.setParams({
        "lstRecordId": selectedIds
    });
Related Topic