Lightning Data Service

In this blog post, we are going to see Lightning data service. With the New Lightning Data services, you can able to perform load, create, edit, or delete a record in your component without requiring Apex code. If you think on a high level, lightning Data services are sort of standard controllers for lighting. Another great advantage too with the Lightning Data services is your application will be more on client side app rather than to be server side apps. That’s so cool!  You can implement the Lighting data services by using force:recordData tag.

Let’s take the Quick look:-
Loading Record or Preview:-

To load the data with force:recordData tag, specify the ID of the record to be loaded, a list of fields, and the attribute to which to assign the loaded record. Or you can specify the layout Type so that all field on the layout will be loaded. If you specify the fields it will display on those filed and if you specify the Layout it will display the all the fields in the layout. Here is the example to show the Account Layout

</pre>
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride" access="global" >

<aura:attribute name="recordId" type="String" />
<aura:attribute name="recorddetails" type="Opportunity" />

<force:recordData recordId="{!v.recordId}"
targetRecord="{!v.recorddetails}"
layoutType="FULL"
fields="Name,Phone,type,Industry"/>


</aura:component>
<pre>

 

By default, force:recordData is not included any UI render. You need to manually include by using outputText or other ways. force:recordData component will provide following methods
getNewRecord: Loads a record template and sets it to force:recordPreview’s targetRecord attribute, including predefined values for the entity and record type.
reloadRecord: Performs the same load function as on init using the current configuration values (recordId, layoutType, mode, and others).
saveRecord: Saves the record.
deleteRecord: Deletes the record.

Editing Record / Saving Record
Now if you see the above code, it’s just display data . not let us modify the code to perform the data edit. Remember you are going to use the lighting component controller to save the data in this case, not apex code. That’s the advantage of the Lightning Data services. See the below code 

<pre><aura:component implements="flexipage:availableForRecordHome,force:hasRecordId"> 
 
 <aura:attribute name="record" type="Object" />
 <aura:attribute name="editRecord" type="Account" />
 
 <force:recordData aura:id="editRec"
 layoutType="FULL"
 recordId="{!v.recordId}"
 targetRecord="{!v.record}"
 targetFields="{!v.editRecord}"
 mode="EDIT" />
 
 <lightning:input aura:id="recordName" name="Name" label="Name"
 value="{!v.editRecord.Name}" required="true"/>
 <lightning:input aura:id="phone" Name="Phone" label="Phone"
 value="{!v.editRecord.CloseDate}" type="phone"/>
 
 <lightning:input aura:id="Type" Name="Type" label="Type"
 value="{!v.editRecord.Amount}" type="number"/>
 
 <lightning:button label="Save Record" onclick="{!c.handleSave}"
 variant="brand" class="slds-m-top--medium"/>
</aura:component>
</pre>

If You see now the data is handling the controller as shown below.

({
    handleSave: function(component, event, helper) {
        component.find("editRec").saveRecord($A.getCallback(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                console.log("Save completed successfully.");
            }
        }));}
})

Your Component controller calls saveRecord() method. The saveRecord() method takes a single callback function, SaveRecordResult, as its only parameter. SaveRecordResult includes a state attribute that tells you whether the save was successful, along with other information you can use to handle the result of the operation.

Creating Records:-
So for we have seen the code to Edit and Preview the data. To create a record using Lightning Data Service, declare force:recordData without assigning a recordId. Next, load a record template by calling the getNewRecord function on force:recordData. Finally, apply values to the new record, and save the record by calling the saveRecord function on force:recordData. Here is the below Component.


<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride" access="global" >

<aura:attribute name="newAcc" type="Object" />
<aura:attribute name="newAccIns" type="Account" />
<force:recordData aura:id="accCreate"
layoutType="FULL"
targetRecord="{!v.newAcc}"
targetFields="{!v.newAccIns}"
/>

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

	<lightning:input aura:id="newName" name="Name" label="Name"
value="{!v.newAccIns.Name}" required="true"/>
	<lightning:button label="Cancel" onclick="{!c.handleCancel}" class="slds-m-top--medium" />
	<lightning:button label="Save " onclick="{!c.handleSave}"
variant="brand" class="slds-m-top--medium"/>


</aura:component>

Here is the controller which calls getNewRecord() method on the initialization of component. Once you click on the save that invoke the saveRecord().

({
    doInit: function(component, event, helper) {
        component.find("accCreate").getNewRecord(
            "Account", // sObject type (entityApiName)
            null, // recordTypeId
            false // skip cache?

        );
    },

    handleSave: function(component, event, helper) {
        component.find("accCreate").saveRecord(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                // Success! Prepare a toast UI message
                var resultsToast = $A.get("e.force:showToast");
                resultsToast.setParams({
                    "title": "Account  Saved",
                    "message": "The new Account  was created."
                });

                // Update the UI: close panel, show toast, refresh account page
                $A.get("e.force:closeQuickAction").fire();
                resultsToast.fire();

                // Reload the view so components not using force:recordData
                // are updated
                $A.get("e.force:refreshView").fire();
            }

        });
    },

    handleCancel: function(component, event, helper) {
        $A.get("e.force:closeQuickAction").fire();
    },
})

Deleting Record:-
To perform the delete operation, call deleteRecord on the force:recordData component from the appropriate controller action handler. deleteRecord takes one argument, a callback function to be invoked when the operation completes. This callback function receives a SaveRecordResult as its only parameter. SaveRecordResult includes a state attribute that indicates success or error and other details you can use to handle the result of the operation.Here is the code.

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId"><force:recordData aura:id="recDel"
recordId="{!v.recordId}"
fields="Id"
/>
<div class="slds-form-element">
	<lightning:button
label="Delete Record"
onclick="{!c.handleDeleteRecord}"
variant="brand" />
</div>
</aura:component>

In the component’s JavaScript controller, call the deleteRecord() method.
deleteRecord() method takes a similar callback function as the saveRecord()


({
handleDeleteRecord: function(component, event, helper) {
component.find("recordHandler").deleteRecord($A.getCallback(function(deleteResult) {
if (deleteResult.state === "SUCCESS" || deleteResult.state === "DRAFT") {
console.log("Record is deleted.");
}

}));
}
})

Here is the github url for complete code

https://github.com/rajamohanvakati/Lightning-Data-Services