# Creating a Record

The simplest way to create a form that enables users create a record is to use `lightning:recordForm`. If you want to customize the form layout or preload custom values, use `lightning:recordEditForm`. If you need more customization than the form-based components allow, use `force:recordData`.

## Create a Record using `lightning:recordForm`

To create a record using `lightning:recordForm`, leave out the `recordId` attribute.

This example displays a form that creates an account record with a list of fields. The Cancel and Save buttons are displayed at the bottom of the form.

```xml
<aura:component>
    <aura:attribute name="fields"
                    type="String[]"
                    default="['Name', 'Industry']"/>
    <lightning:recordForm objectApiName="Account"
                          fields="{!v.fields}"/>
</aura:component>
```

When the record saves successfully, the fields display pencil icons to denote that inline editing is available. This view is displayed until you refresh or reload the page. Then the form redisplays the record fields without data, ready to create a new record.

Alternatively, use the `Full` layout type, which loads all fields from the full layout to display a form that creates a record. The `columns` attribute displays the record fields in two columns that are evenly sized.

```xml
<aura:component>
    <lightning:recordForm objectApiName="Account"
                          layoutType="Full"
                          columns="2"/>
</aura:component>
```

## Customize Error Handling in `lightning:recordForm`

When an error is encountered during save, `lightning:recordForm` displays an error message at the top of the form. You can provide additional error handling using the `onerror` event handler.

This example displays a toast message when an error is returned.

```xml
<aura:component>
    <aura:attribute name="fields"
                    type="String[]"
                    default="['Name', 'Industry']"/>

    <!-- Displays toast notifications -->
    <lightning:notificationsLibrary aura:id="notifLib" />
    <lightning:recordForm
        objectApiName="Account"
        fields="{!v.fields}"
        onerror="{!c.handleError}"/>
</aura:component>
```

To return the error message, use `event.getParam("message")`.

```javascript
({
    handleError: function (cmp, event, helper) {
        cmp.find('notifLib').showToast({
            "title": "Something has gone wrong!",
            "message": event.getParam("message"),
            "variant": "error"
        });
    }
})
```

To customize the form behavior when a record saves successfully, use the `onsuccess` event handler.

If you want to provide a custom layout or load custom field values when the form displays, use the `lightning:recordEditForm` component as shown in the next section.

## Create a Record with a Custom Layout Using `lightning:recordEditForm`

To provide a custom layout for your form fields, use the `lightning:recordEditForm` component.

Pass in the fields to `lightning:inputField`, which displays an input control based on the record field type.

This example creates a custom layout using the Grid utility classes in Lightning Design System.

```xml
<aura:component>
    <lightning:recordEditForm objectApiName="Account">
        <lightning:messages />
            <div class="slds-grid">
                <div class="slds-col slds-size_2-of-3">
                    <lightning:inputField fieldName="Name"/>
                </div>
                <div class="slds-col slds-size_1-of-3">
                    <lightning:inputField fieldName="Industry"/>
                </div>
            </div>
        <lightning:button class="slds-m-top_small" type="submit" label="Create new" />
    </lightning:recordEditForm>
</aura:component>
```

When a server error is encountered,`lightning:recordEditForm` displays an error message above the form fields. To enable automatic error handling, include the `lightning:messages` component. Alternatively, provide your own error handling using the `onerror` event handler.

Another feature that `lightning:recordEditForm` provides that’s not available with `lightning:recordForm` is preset custom field values, as shown in the next section.

## Prepopulate Field Values

To provide a custom field value when the form displays, use the `value` attribute on `lightning:inputField`. If you're providing a record ID, the value returned by the record on load does not override this custom value.

Alternatively, set the field value using this syntax.

```javascript
cmp.find("nameField").set("v.value", "My New Account Name");
```

:::note
For more information, see [lightning:recordEditForm](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordEditForm/documentation).
:::

If you require more customization when creating a record than what `lightning:recordForm` and `lightning:recordEditForm` allow, consider using `force:recordData`.

## Create a Record via a Custom User Interface Using `force:recordData`

To create a record using `force:recordData`, leave out the `recordId` attribute. 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 [Editing a Record](/docs/platform/aura-platform/guide/data-service-save-record.md#editing-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                                                                                                                                                    |
| --------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `objectApiName` | String   | The object API name for the new record.                                                                                                                        |
| `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`

```xml
<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" 
                      fields="FirstName,LastName,Title"
                      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>
```

:::note
To improve performance, we recommend using the `fields` attribute to query only the fields you need. Use `layoutType` only if you want the administrator, not the component, to control the fields that are provisioned. The component must handle receiving every field that is assigned to the layout for the context user.
:::

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`

```javascript
({
    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));
                }
            });
        }
    }
})
```

The `doInit` init handler calls `getNewRecord()` on the `force:recordData` component, passing in a simple callback handler. This call returns a [Record](https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_responses_record.htm) object to create an empty contact record, which is used by the contact form in the component’s markup.

:::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 [Editing a Record](/docs/platform/aura-platform/guide/data-service-save-record.md#editing-a-record), and then updating the user interface.

:::note
The helper function, `validateContactForm`, isn’t shown. It simply validates the form values. For an example of this validation, see [Lightning Action Examples](/docs/platform/aura-platform/guide/data-service-example.md#lightning-action-examples).
:::

**See Also**

- [*Component Library*: `lightning:recordForm`](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordForm/documentation)
- [*Component Library*: `lightning:recordEditForm`](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordEditForm/documentation)
- [Editing a Record](/docs/platform/aura-platform/guide/data-service-save-record.md)
- [Configure Components for Lightning Experience Record Pages](/docs/platform/aura-platform/guide/components-config-for-app-builder-record-home.md)
- [Configure Components for Record-Specific Actions](/docs/platform/aura-platform/guide/components-using-lex-s1-config-action-recordid.md)
- [Controlling Access](/docs/platform/aura-platform/guide/access-intro.md)
