[SalesForce] Lightning Data Table inline edit

How best to update records with changes made in a lightning datatable? The original list of accounts is not automatically updated by inline changes, and the 'draftValues' retrieved when the update 'save' button is clicked, don't have the ID of the record, so I can't update.

For example, when I click update, I get

draftvalues: [{"Industry":"kjnkjnk","id":"row-0"}]
acctList: [{"Id":"001n000000UX9ZYAA2","Name":"CIA","Type":"Prospect"},{"Id":"001n000000UXByNAAX","Name":"Company","Type":"Prospect"},{"Id":"001n000000UXBmdAAP","Name":"Company","Type":"Prospect"},{"Id":"001n000000UXAfYAA1","Name":"Company","Type":"Prospect"},{"Id":"001n000000UXAAdAAP","Name":"Company","Type":"Prospect"},{"Id":"001n000000UXB8SAA5","Name":"Company","Type":"Prospect"},{"Id":"001n000000UXAPDC23","Name":"Company","Type":"Prospect"},{"Id":"001n000000UXASMZX3","Name":"Company","Type":"Prospect"}]

So, first list doesn't have ids, and second lot doesn't have changes = can't update.

Do I have to manually associate the 'draftvalues' with the id of the record, or is there some easier way to do this?

I have:

cmp:

<aura:attribute type="Account[]" name="acctList"/>
<aura:attribute name="mycolumns" type="List"/>
<aura:attribute name="sortedBy" type="String" default="Name"/>
<aura:attribute name="sortedDirection" type="String" default="asc"/>

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

<lightning:datatable data="{!v.acctList}" 
                     columns="{!v.mycolumns}" 
                     keyField="id"
                     hideCheckboxColumn="true"
                     onsort="{!c.updateColumnSorting}"
                     sortedBy="{!v.sortedBy}"  
                     sortedDirection="{!v.sortedDirection}"
                     onsave="{! c.handleSave }"/>

controller.js:

fetchAccounts : function(component, event, helper) {
    component.set('v.mycolumns', [
        {label: 'Account Name', fieldName: 'Name', type: 'text', sortable: true, editable: true},
        {label: 'Industry', fieldName: 'Industry', type: 'text', sortable: true, editable: true},
        {label: 'Type', fieldName: 'Type', type: 'Text', sortable: true, editable: true}
    ]);
    var action = component.get("c.fetchAccts");
    action.setParams({
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            component.set("v.acctList", response.getReturnValue());
            helper.sortData(component, component.get("v.sortedBy"), component.get("v.sortedDirection"));
        }
    });
    $A.enqueueAction(action);
},
 handleSave: function(cmp, event, helper){
  var action = cmp.get("c.saveAccts");
  var acctList = cmp.get("v.acctList");
  var draftList = event.getParam('draftValues');
          console.log('draftValues-> ' + JSON.stringify(draftList));
  console.log('acctList->' + JSON.stringify(acctList));
  console.log(acctList);
  action.setParams({acctList: draftList});
  action.setCallback(this, function(response){
     console.log('hi'); 
  });
  $A.enqueueAction(action);

AccountListController.apxc:

 @AuraEnabled
public static List < Account > fetchAccts() {
    return [ SELECT Id, Name, Industry, Type FROM Account LIMIT 10 ];
}

@AuraEnabled
public static String saveAccts(List<account> acctList){
    System.debug(acctList);
    System.debug('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
    update acctList;
    return 'hi';
}

Best Answer

The keyField should be Id, not id. Note that JavaScript is case sensitive, and as such, Lightning is also case-sensitive. You should get the correct Id so long as you use the correct casing.