Creating a Record

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.
  1. Call getNewRecord to create an empty record from a record template. You can use this record as the backing store for a form or otherwise have its values set to data intended to be saved.
  2. Call saveRecord to commit the record. This is described in Saving a Record.

Create an Empty Record from a Record Template

To create an empty record from a record template, you can’t set a recordId on the force:recordData tag. Without a recordId, Lightning Data Service doesn’t load an existing record.

In your component’s init or another handler, call the getNewRecord on force:recordData. getNewRecord takes the following arguments.
Attribute Name Type Description
entityApiName String The entity API name for the sObject of the record to be created.
recordTypeId String The 18 character ID of the record type for the new record.

If not specified, the default record type for the object is used, as defined in the user’s profile.

skipCache Boolean Whether to load the record template from the server instead of the client-side Lightning Data Service cache. Defaults to false.
callback Function A function invoked after the empty record is created. This function receives no arguments.

getNewRecord doesn’t return a result. It simply prepares an empty record and assigns it to the targetRecord attribute.

Creating a Record

The following example illustrates the essentials of creating a record using Lightning Data Service. This example is intended to be added to an account record Lightning page.

ldsCreate.cmp
<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}" />
                      
    <div class="slds-page-header" role="banner">
        <p class="slds-text-heading--label">Create Contact</p>
    </div>

    <!-- Display Lightning Data Service errors -->
    <aura:if isTrue="{!not(empty(v.newContactError))}">
        <div class="recordError">
            <ui:message title="Error" severity="error" closable="true">
                {!v.newContactError}
            </ui:message>
        </div>
    </aura:if>

    <!-- Display the new contact form -->
    <div class="slds-form--stacked">
        <lightning:input aura:id="contactField" name="firstName" label="First Name"
                         value="{!v.simpleNewContact.FirstName}" required="true"/>
      
        <lightning:input aura:id="contactField" name="lastname" label="Last Name"
                      value="{!v.simpleNewContact.LastName}" required="true"/>
                
        <lightning:input aura:id="contactField" name="title" label="Title"
                      value="{!v.simpleNewContact.Title}" />
                      
        <lightning:button label="Save contact" onclick="{!c.handleSaveContact}"
                   variant="brand" class="slds-m-top--medium"/>
   </div>

</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.
ldsCreateController.js
({
    doInit: function(component, event, helper) {
        // Prepare a new record from template
        component.find("contactRecordCreator").getNewRecord(
            "Contact", // sObject type (entityApiName)
            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.sobjectType);
            })
        );
    },

    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));
                }
            });
        }
    }
})
The doInit init handler calls getNewRecord() on the force:recordData component, passing in a simple callback handler. This call creates a new, empty contact record, which is used by the contact form in the component’s markup.
Note

Note

The callback passed to getNewRecord() must be wrapped in $A.getCallback() to ensure correct access context when the callback is invoked. If the callback is passed in without being wrapped in $A.getCallback(), any attempt to access private attributes of your component results in access check failures.

Even if you’re not accessing private attributes, it’s a best practice to always wrap the callback function for getNewRecord() in $A.getCallback(). Never mix (contexts), never worry.

The handleSaveContact handler is called when the Save Contact button is clicked. It’s a straightforward application of saving the contact, as described in Saving a Record, and then updating the user interface.

Note

Note

The helper function, validateContactForm, isn’t shown. It simply validates the form values. For an example of this validation, see Lightning Data Service Example.