Lightning Data Service - Salesforce new Apex alternative - Part 2

We have looked on some basic code for Loading and Updating a record using Lightning Design System in my last blog post. Here we are going to work on creating and deleting a record in Lightning Component using Lightning Design System.

1. Creating a Record:
For creating a new record using LDS we declare force:recordData without assigning a recordId unlike what we use to do with Load and Update record. And then we load a record template by calling the getNewRecord function on force:recordData and finally we handle saving data using saveRecord in our 'handleSaveRecord' function.

Lightning Components Developer guide already have some basic code on creating a Contact record (Reference Link). We are going to extend that code a bit to first create a new Account record and then create a new Contact record by linking it to the Account that we created all in one single shot.

Below we are going to create a new Lighting Component from Developer Console by navigating to File-->New-->Lightning Component and give some name to your Lightning Component and click Submit. Copy past below code in Component editor and save it using File-->Save

LDS_Create_Record.cmp Code:
1:  <aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,force:hasRecordId">  
2:    <!--Load LDS from static resource-->  
3:    <ltng:require styles="/resource/SLDS/assets/styles/salesforce-lightning-design-system.css"/>  
4:    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>  
5:    <!--attributes to store record related information-->  
6:    <aura:attribute name="acc" type="Object"/>  
7:    <aura:attribute name="accRecord" type="Object"/>  
8:    <aura:attribute name="cont" type="Object"/>  
9:    <aura:attribute name="contRecord" type="Object"/>  
10:    <aura:attribute name="accError" type="String"/>  
11:    <aura:attribute name="contError" type="String"/>  
12:    <!--LDS to store account info-->  
13:    <force:recordData aura:id="rcd1"  
14:             layoutType="FULL"  
15:             targetRecord="{!v.acc}"   
16:             targetFields="{!v.accRecord}"  
17:             targetError="{!v.accError}"  
18:             />   
19:    <!--LDS to store contact info-->  
20:    <force:recordData aura:id="rcd2"  
21:             layoutType="FULL"  
22:             targetRecord="{!v.cont}"   
23:             targetFields="{!v.contRecord}"  
24:             />    
25:    <div><p><b><h1 style="color:blue;font-family:verdana;">Test Lightning Data Service: Create Record!</h1></b></p></div>  
26:    <center><lightning:button label="Save" onclick="{!c.handleSaveRecord}" variant="brand" class="slds-m-top--medium"/></center><br/>  
27:    <div class="slds-page-header" role="banner">  
28:      <center><p class="slds-text-heading--label">Create Account Record</p></center>  
29:    </div>  
30:    <!-- Display the new Account form -->  
31:    <div class="slds-form--stacked">  
32:      <lightning:input aura:id="accField" name="name" label="Account Name" value="{!v.accRecord.Name}" required="true"/>  
33:      <lightning:input aura:id="accField" name="name" label="Account Phone" value="{!v.accRecord.Phone}"/>  
34:    </div>  
35:    <div class="slds-page-header" role="banner">  
36:      <center><p class="slds-text-heading--label">Create Contact Record</p></center>  
37:    </div>    
38:    <!-- Display the new contact form -->  
39:    <div class="slds-form--stacked">  
40:      <lightning:input aura:id="contField" name="firstName" label="Contact First Name"  
41:               value="{!v.contRecord.FirstName}" required="true"/>  
42:      <lightning:input aura:id="contField" name="lastname" label="Contact Last Name"  
43:               value="{!v.contRecord.LastName}" required="true"/>  
44:      <lightning:input aura:id="contField" name="title" label="Title"  
45:               value="{!v.contRecord.Title}" />  
46:    </div>    
47:  </aura:component>  

Copy paste below code in Controller editor and save using File-->Save. Here in this code we have two functions (doInit and handleSaveRecord), "doInit" function will instantiate an empty Account and Contact record on component loading and "handleSaveRecord" will handle logic for creating Account record first and then Contact.

LDS_Create_Record.js Code:
1:  ({  
2:    doInit: function(component, event, helper) {  
3:      //set empty account object template to 'rcd1' attribute  
4:      component.find("rcd1").getNewRecord(  
5:        "Account", // sObject type (entityApiName)  
6:        null,   // recordTypeId  
7:        false,   // skip cache?  
8:        $A.getCallback(function() {  
9:          var rec = component.get("v.acc");  
10:          var error = component.get("v.accError");  
11:          if(error || (rec === null)) {  
12:            console.log("Error initializing record template: " + error);  
13:            return;  
14:          }  
15:          console.log("Record template initialized: " + rec.sobjectType);  
16:        })  
17:      );  
18:      //set empty contact object template to 'rcd2' attribute  
19:      component.find("rcd2").getNewRecord(  
20:        "Contact", // sObject type (entityApiName)  
21:        null,   // recordTypeId  
22:        false,   // skip cache?  
23:        $A.getCallback(function() {  
24:          var rec = component.get("v.cont");  
25:          var error = component.get("v.contError");  
26:          if(error || (rec === null)) {  
27:            console.log("Error initializing record template: " + error);  
28:            return;  
29:          }  
30:          console.log("Record template initialized: " + rec.sobjectType);  
31:        })  
32:      );      
33:    },  
34:    handleSaveRecord: function(component, event, helper) {  
35:      //create a new account record using saveRecord function  
36:      component.find("rcd1").saveRecord($A.getCallback(function(saveResult) {  
37:        //if success go ahead and create a new contact record  
38:        if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {  
39:          console.log('************Record State************' + saveResult.state + '************Account Id************' + component.get("v.accRecord.Id"));  
40:          alert('Account record is Succeffully Created with Id: ' + component.get("v.accRecord.Id"));  
41:          //setting accountid value on contact to connect them  
42:          component.set("v.contRecord.AccountId", component.get("v.accRecord.Id"));  
43:          //create a new contact record using saveRecord function  
44:          component.find("rcd2").saveRecord($A.getCallback(function(saveResult) {  
45:            //if success show toast message with account and contact ids  
46:            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {  
47:              console.log('************Record State************' + saveResult.state + '************Contact Id************' + component.get("v.contRecord.Id"));  
48:              alert('Contact record is Succeffully Created with Id: ' + component.get("v.contRecord.Id"));  
49:              var resultsToast = $A.get("e.force:showToast");  
50:              resultsToast.setParams({  
51:                "title": "Account and Contact are successfully created!",  
52:                "message": "Account Id: " + component.get("v.accRecord.Id") + " - Contact Id: " + component.get("v.contRecord.Id")  
53:              });  
54:    ;              
55:            }   
56:            //show error message on fialure  
57:            else if (saveResult.state === "ERROR") {  
58:              //display alert on error state  
59:              alert('Error Occured while creating a Contact');  
60:            }        
61:          }));                          
62:        }   
63:        //show error message on fialure  
64:        else if (saveResult.state === "ERROR") {  
65:          //display alert on error state  
66:          alert('Error Occured while creating an Account');  
67:        }        
68:      }));  
69:    }    
70:  })  

Finally we are going to expose our Lighting Component using custom Lighting Component Tab. If we observe our LDS_Create_Record.cmp code above we have implemented "force:appHostable" and that is what makes our Component available for creating a custom Lightning Component Tab. Navigate to Setup-->Tabs-->New under Lighting Component Tabs, give some name for you tab and then click Save and add it to your App so that it is ready for access.

Now when we click on our new component Tab we should be able to view our component to input Account and Contact details (In our component we just added few required fields for Account and Contact). Once you input all required fields, click Save and we should see a toast message with Account and Contact Ids

2. Deleting a Record:
Deleting a record is just as simple as loading record using Lightning Design System. Lets just go ahead and create a Lighting Component and place it on Account detail page using Lighting App Builder. Below are component and controller code blocks.

LDS_Delete_Record.cmp Code:
1:  <aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickActionWithoutHeader,force:hasRecordId">  
2:    <!--Load LDS from static resource-->  
3:    <ltng:require styles="/resource/SLDS/assets/styles/salesforce-lightning-design-system.css"/>  
4:    <!--Attributes-->  
5:    <aura:attribute name="recordError" type="String" access="private"/>  
6:    <!--LDS to load record-->  
7:    <force:recordData aura:id="recordHandler"  
8:             recordId="{!v.recordId}"  
9:             fields="Id"  
10:             targetError="{!v.recordError}"  
11:             />  
12:    <div><p><b><h1 style="color:blue;font-family:verdana;">Test Lightning Data Service: Delete Record!</h1></b></p></div><br/><br/>  
13:    <div class="slds-form-element">  
14:      <!--Button to delete record-->  
15:      <center><lightning:button label="Delete Record"  
16:                   onclick="{!c.handleDeleteRecord}"  
17:                   variant="brand" /></center>  
18:    </div>  
19:  </aura:component>  

LDS_Delete_Record.js Code: Here in this controller code we have 'handleDeleteRecord' function to first retrieve record and delete it from database using 'deleteRecord' function. And upon on success we are going to display an alert message and navigate user to Home Page.
1:  ({  
2:    handleDeleteRecord: function(component, event, helper) {  
3:      //Find current record and delete using 'deleteRecord' function  
4:      component.find("recordHandler").deleteRecord($A.getCallback(function(deleteResult) {  
5:        //if success then show alert message and navigate user to home page  
6:        if (deleteResult.state === "SUCCESS" || deleteResult.state === "DRAFT") {      
7:          alert('Successfully deleted record with Id: ' + component.get("v.recordId"));  
8:          //show toast message upon success  
9:          var resultsToast = $A.get("e.force:showToast");  
10:          resultsToast.setParams({  
11:            "title": "Home Page",  
12:            "message": "Successfully navigated to Home Page after deleted record with Id: " + component.get("v.recordId")  
13:          });  
15:          //navigate user to home page  
16:          window.location.replace("/");  
17:        }   
18:        //if error then display some error message  
19:        else if (deleteResult.state === "ERROR") {  
20:          console.log('Problem deleting record, error: ' + JSON.stringify(deleteResult.error));  
21:          alert('Error Occured: ' + component.get("v.recordId"));  
22:        } else {  
23:          console.log('Unknown problem, state: ' + deleteResult.state + ', error: ' + JSON.stringify(deleteResult.error));  
24:        }  
25:      }));      
26:    }  
27:  })  

Limitations with Lighting Data Service:

1. Currently Lighting Data Service is in beta version (As of this blog post dated 06/20/2017).
2. Lightning Data Service is available in Lightning Experience and Salesforce1.
3. Lightning Data Service is not supported when used with containers like Lightning Components for Visualforce, Lightning Out, or Communities.
4. Lighting Data Service operates on One record at a time (It cannot work on multiple records at a time).

For some additional notes on considerations and limitations with Lightning Data Service please refer to this Link.

Hope you like reading this and any feedback or comments are really appreciated - Tks


  1. Salesforce CRM tool helps business to track customer information of your business and the tool provides the detailed information of customer activities related to your business….You provide us detailed information on the complete guidance of Salesforce CRM tool.

    Salesforce Training in Chennai
    Salesforce Training

  2. Salesforce began with the vision of reinventing Customer Relationship Management (CRM). Salesforce users can configure their CRM application. In the system, there are tabs such as “Contacts,” “Reports,” and “Accounts.” Each tab contains associated information. Configuration can be done on each tab by adding user-defined custom fields.
    Salesforce Tutorial

  3. Nice post. I study something more challenging on completely different blogs everyday. It is going to all the time be stimulating to learn content from different writers and observe a bit one thing from their store. Thanks for sharing.

    Salesforce Training in Hyderabad | Salesforce Lightning Training in Hyderabad

  4. I must appreciate you for providing such a valuable content for us.Helped a lot in increasing my knowledge on Salesforce. Know More Details about click here.

  5. Wonderful post!!Thank you for sharing this info with us.
    Keep updating I would like to know more updates on this topic
    Very useful content, I would like to suggest this blog to my friends.

    Salesforce Training Chennai
    Salesforce crm Training in Chennai


Post a Comment

Popular posts from this blog

Displaying Toast Message from Modal in Lightning Components

Lightning RecordForm - An enhanced Lightning Data Service

Lightning Component to display dynamic sObject data