In the last post we study about Lightning Data service in LWC or Aura. So in this post we will continue our progress and complete the remaining part of how can use Lightning Data service in LWC or Aura.

In previous post we learn about tags which we can use for LDS. We also get saveResult in controller using that we can get State of the operation and can display different message to user based on different state. LDS also support Data caching so if user lost the connection while process data LDS save that in cache with status Draft. In this part we will continue with creating a new record using template.
Create a Record using Lightning data Service in LWCcor Aura
To create a record using Lightning Data Service in LWC, we can use lightning-record-form or lightning-record-edit-form
. While in Lightning we have lightning:recordForm, lightning:recordEditForm and force:recordData. So when creating a new record we need to 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.
Create an Empty Record from a Record Template
Firstly, to create an empty record from a record template, we don’t need to set a recordId on the force:recordData tag. Without a recordId, Lightning Data Service doesn’t load an existing record. So in our component’s inithandler, will call the getNewRecord on force:recordData.
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
<aura:attribute name="newContact" type="Object"/>
<aura:attribute name="simpleNewContact" type="Object"/>
<aura:attribute name="newContactError" type="String"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<force:recordData aura:id="contactRecordCreator"
layoutType="FULL"
targetRecord="{!v.newContact}"
targetFields="{!v.simpleNewContact}"
targetError="{!v.newContactError}" />
<!-- Display the new contact form -->
<div class="Create Contact">
<lightning:card iconName="action:new_contact" title="Create Contact">
<div class="slds-p-horizontal--small">
<lightning:input aura:id="contactField" label="First Name" value="{!v.simpleNewContact.FirstName}"/>
<lightning:input aura:id="contactField" label="Last Name" value="{!v.simpleNewContact.LastName}"/>
<lightning:input aura:id="contactField" label="Title" value="{!v.simpleNewContact.Title}"/>
<br/>
<lightning:button label="Save Contact" variant="brand" onclick="{!c.handleSaveContact}"/>
</div>
</lightning:card>
</div>
<!-- Display Lightning Data Service errors -->
<aura:if isTrue="{!not(empty(v.newContactError))}">
<div class="recordError">
{!v.newContactError}</div>
</aura:if>
</aura:component>
This component doesn’t set the recordId attribute of force:recordData. This tells Lightning Data Service to expect a new record. Here, that’s created in the component’s init handler.
({
doInit: function(component, event, helper) {
// Prepare a new record from template
component.find("contactRecordCreator").getNewRecord(
"Contact", // sObject type (objectApiName)
null, // recordTypeId
false, // skip cache?
$A.getCallback(function() {
var rec = component.get("v.newContact");
var error = component.get("v.newContactError");
if(error || (rec === null)) {
console.log("Error initializing record template: " + error);
return;
}
console.log("Record template initialized: " + rec.apiName);
})
);
},
handleSaveContact: function(component, event, helper) {
if(helper.validateContactForm(component)) {
component.set("v.simpleNewContact.AccountId", component.get("v.recordId"));
component.find("contactRecordCreator").saveRecord(function(saveResult) {
if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
// record is saved successfully
var resultsToast = $A.get("e.force:showToast");
resultsToast.setParams({
"title": "Saved",
"message": "The record was saved."
});
resultsToast.fire();
} else if (saveResult.state === "INCOMPLETE") {
// handle the incomplete state
console.log("User is offline, device doesn't support drafts.");
} else if (saveResult.state === "ERROR") {
// handle the error state
console.log('Problem saving contact, error: ' + JSON.stringify(saveResult.error));
} else {
console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
}
});
}
}
})
Delete a Record using Lightning data Service in LWCcor Aura
So to delete a record using Lightning Data Service, we need to call deleteRecord on the force:recordData component. And pass in a callback function to be invoked after the delete operation completes. 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 we can use to handle the result of the operation.
Sample Code
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
<aura:attribute name="recordError" type="String" access="private"/>
<force:recordData aura:id="recordHandler"
recordId="{!v.recordId}"
fields="Id"
targetError="{!v.recordError}"
recordUpdated="{!c.handleRecordUpdated}" />
<!-- Display the delete record form -->
<div class="Delete Record">
<lightning:card iconName="action:delete" title="Delete Record">
<div class="slds-p-horizontal--small">
<lightning:button label="Delete Record" variant="destructive" onclick="{!c.handleDeleteRecord}"/>
</div>
</lightning:card>
</div>
<!-- Display Lightning Data Service errors, if any -->
<aura:if isTrue="{!not(empty(v.recordError))}">
<div class="recordError">
{!v.recordError}</div>
</aura:if>
</aura:component>
For minimum delete process we don’t need any other fields but if we want to display data as well that we can pass them as parameter.
({
handleDeleteRecord: function(component, event, helper) {
component.find("recordHandler").deleteRecord($A.getCallback(function(deleteResult) {
// NOTE: If you want a specific behavior(an action or UI behavior) when this action is successful
// then handle that in a callback (generic logic when record is changed should be handled in recordUpdated event handler)
if (deleteResult.state === "SUCCESS" || deleteResult.state === "DRAFT") {
// record is deleted
console.log("Record is deleted.");
} else if (deleteResult.state === "INCOMPLETE") {
console.log("User is offline, device doesn't support drafts.");
} else if (deleteResult.state === "ERROR") {
console.log('Problem deleting record, error: ' + JSON.stringify(deleteResult.error));
} else {
console.log('Unknown problem, state: ' + deleteResult.state + ', error: ' + JSON.stringify(deleteResult.error));
}
}));
},
})
When the record is deleted, navigate away from the record page. Otherwise, we see a “record not found” error when the component refreshes. Here the controller uses the objectApiName property in the SaveRecordResult provided to the callback function, and navigates to the object home page.
While in LWC we can use UI API to delete the record. So using this API we can delete one record at a time
Syntax
import { deleteRecord } from 'lightning/uiRecordApi';
deleteRecord(recordId: string): Promise<void>
Sample Code
delete(event) {
deleteRecord(this.recordId)
.then(() => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: 'Record deleted',
variant: 'success'
})
);
// Navigate to a record home page after
// the record is deleted, such as to the
// contact home page
this[NavigationMixin.Navigate]({
type: 'standard__objectPage',
attributes: {
objectApiName: 'Contact',
actionName: 'home',
},
});
})
.catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error deleting record',
message: error.body.message,
variant: 'error'
})
);
});
}
Record Changes
If we want to perform any action other then rerendering we need to handle the recordUpdated event. We can handle record loaded, updated, and deleted changes, applying different actions to each change type. For example, different actions apply to opportunities at different stages of the sales cycle.
Note: Lightning Data Service notifies listeners about data changes only if the changed fields are the same as in the listener’s fields or layout.
Sample Code
<force:recordData aura:id="forceRecord"
recordId="{!v.recordId}"
layoutType="FULL"
targetRecord="{!v._record}"
targetFields="{!v.simpleRecord}"
targetError="{!v._error}"
recordUpdated="{!c.recordUpdated}" />
({
recordUpdated: function(component, event, helper) {
var changeType = event.getParams().changeType;
if (changeType === "ERROR") { /* handle error; do this first! */ }
else if (changeType === "LOADED") { /* handle record load */ }
else if (changeType === "REMOVED") { /* handle record removal */ }
else if (changeType === "CHANGED") { /* handle record change */ }
})
When loading a record in edit mode, the record is not automatically updated to prevent edits currently in progress from being overwritten. To update the record, use the reloadRecord method in the action handler.
Sample Code
<force:recordData aura:id="forceRecord"
recordId="{!v.recordId}"
layoutType="FULL"
targetRecord="{!v._record}"
targetFields="{!v.simpleRecord}"
targetError="{!v._error}"
mode="EDIT"
recordUpdated="{!c.recordUpdated}" />
({
recordUpdated : function(component, event, helper) {
var changeType = event.getParams().changeType;
if (changeType === "ERROR") { /* handle error; do this first! */ }
else if (changeType === "LOADED") { /* handle record load */ }
else if (changeType === "REMOVED") { /* handle record removal */ }
else if (changeType === "CHANGED") {
/* handle record change; reloadRecord will cause you to lose your current record, including any changes you’ve made */
component.find("forceRecord").reloadRecord();}
}
})
So we have cover all the operation which are possible using Lightning Data Service in LWC or Aura. But there are still few use case where we need Apex as well. For example:
- For bulk data process we need apex. So we can’t use it as StandardsetController replacement.
- If we need to fetch data of more than 3 level or need to display child records then we need apex for that.
Like My Facebook page for more updates.
Let me know what you like most about Lightning Data Service in comments. Happy programming 🙂
can u tell me where we can use lds
Whenever you want to perform simple record creation, update we can use lds. Its kind of standard controller in lightning.