Introduction
updateRecord is a crucial function in Lightning Data Service (LDS) that allows you to update Salesforce records without writing Apex code.
While it’s not a wire adapter like getRecord
, it’s equally important in the LDS toolkit.
In this comprehensive guide, we’ll explore everything you need to know about updateRecord
in LDS, from basic usage to advanced patterns and best practices.
What is Lightning Data Service ?
Before diving into updateRecord
, let’s understand LDS’s role:
Client-side caching: LDS maintains a client-side cache of records
Shared data: Components accessing the same record share a single source of truth
Automatic UI updates: Changes propagate to all components using the same record
Reduced server trips: Minimizes API calls by leveraging the cache
Built-in security: Respects field-level security and sharing settings
Understanding updateRecord
The updateRecord
function is part of the lightning/uiRecordApi
module and provides a declarative way to update Salesforce records in LWC.
Key Features of updateRecord
✅ No Apex required – Pure client-side operation.
✅ Automatic Refresh – Updates all components using the same record.
✅ Automatic security checks – Respects Field Level Security (FLS) and sharing rules.
✅ Optimised performance – Minimizes network calls.
✅ Optimistic UI – Immediate UI update with rollback on failure.
✅ Validation Aware – Honors all standard validation rules.
How to Use 'updateRecord'?
Basic Syntax
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
// 1. Prepare fields to update
const fields = {};
fields['Id'] = recordId; // Required
fields['Account.Name'] = 'New Account Name';
// 2. Execute update
try {
await updateRecord({ fields });
// Show success message
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: 'Record updated',
variant: 'success'
})
);
} catch (error) {
// Handle error
}
Complete Example: Updating an Account
Let’s walk through a complete example of updating an Account record.
1. Create the Component
2. Javascript Controller
// updateAccount.js
import { LightningElement, api, wire } from 'lwc';
import { getRecord, updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';
import ACCOUNT_ID_FIELD from '@salesforce/schema/Account.Id';
export default class UpdateAccount extends LightningElement {
@api recordId; // Automatically populated when component is placed on a record page
accountName;
accountFields = [ACCOUNT_NAME_FIELD];
// Wire service to get the current record
@wire(getRecord, { recordId: '$recordId', fields: '$accountFields' })
wiredAccount({ error, data }) {
if (data) {
this.accountName = data.fields.Name.value;
} else if (error) {
this.showToast('Error', error.body.message, 'error');
}
}
handleNameChange(event) {
this.accountName = event.target.value;
}
async handleUpdate() {
try {
// Create the record input
const fields = {};
fields[ACCOUNT_ID_FIELD.fieldApiName] = this.recordId;
fields[ACCOUNT_NAME_FIELD.fieldApiName] = this.accountName;
const recordInput = { fields };
// Update the record
await updateRecord(recordInput);
// Show success message
this.showToast('Success', 'Account updated successfully', 'success');
} catch (error) {
this.showToast('Error updating record', error.body.message, 'error');
}
}
showToast(title, message, variant) {
this.dispatchEvent(
new ShowToastEvent({
title,
message,
variant
})
);
}
}
How updateRecord Works Under the Hood
Request Preparation: LDS prepares the update request with only changed fields
Client-Side Validation: Checks for required fields and basic validations
Server Call: Makes an API call to update the record
Cache Update: Updates the client-side cache if successful
UI Notification: Propagates changes to all components using the record
Error Handling: Reverts changes and notifies if the update fails
Important Notes About updateRecord
Requires Record ID: You must always include the record Id
Field API Names: Use the full field path (e.g.,
Account.Name
)Error Handling: Always wrap in try-catch
No Wire Adapter: Unlike
getRecord
, this is a function you call
Key Benefits of Using updateRecord
Simplified Code: No need to write Apex for basic updates
Automatic Sharing Enforcement: Respects org sharing settings
Field-Level Security: Only updates fields the user has edit access to
Performance: Optimistic UI updates make applications feel faster
Consistency: All components show the same data simultaneously
Reduced Boilerplate: Handles many common patterns automatically
Advanced Patterns
1. Updating Multiple Fields
import NAME_FIELD from '@salesforce/schema/Account.Name';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
import PHONE_FIELD from '@salesforce/schema/Account.Phone';
// In your update method:
const fields = {};
fields[ID_FIELD.fieldApiName] = this.recordId;
fields[NAME_FIELD.fieldApiName] = this.accountName;
fields[INDUSTRY_FIELD.fieldApiName] = this.industry;
fields[PHONE_FIELD.fieldApiName] = this.phone;
const recordInput = { fields };
await updateRecord(recordInput);
2. Handling Related Records
You can update fields on related records using dot notation:
import CONTACT_NAME_FIELD from '@salesforce/schema/Account.PrimaryContact.Name';
const fields = {};
fields[ID_FIELD.fieldApiName] = this.recordId;
fields[CONTACT_NAME_FIELD.fieldApiName] = 'New Contact Name';
const recordInput = { fields };
await updateRecord(recordInput);
3. Combining with getRecordUi
For more complex scenarios, you can combine with getRecordUi
:
import { getRecordUi, updateRecord } from 'lightning/uiRecordApi';
async handleUpdate() {
// First get the record UI for additional metadata
const recordUi = await getRecordUi({
recordIds: [this.recordId],
layoutTypes: ['Full'],
modes: ['Edit']
});
// Then perform the update
const fields = { /* ... */ };
await updateRecord({ fields });
}
Error Handling Best Practices
Proper error handling is crucial for a good user experience:
async handleUpdate() {
try {
await updateRecord(recordInput);
this.showToast('Success', 'Record updated', 'success');
} catch (error) {
let message = 'Unknown error';
if (Array.isArray(error.body)) {
message = error.body.map(e => e.message).join(', ');
} else if (typeof error.body.message === 'string') {
message = error.body.message;
}
this.showToast('Error updating', message, 'error');
}
}
Performance Considerations
Bulk Updates: For multiple records, consider using Apex
Field Selection: Only include fields you need to update
Network Conditions: Handle poor connectivity gracefully
Caching: LDS automatically caches, but be mindful of stale data
Comparison with Similar Methods
Method | Type | Purpose | Real-time Sync |
---|---|---|---|
updateRecord | Function | Update records | ✅ Yes |
getRecord | Wire Adapter | Read records | ✅ Yes |
deleteRecord | Function | Delete records | ✅ Yes |
When to use updateRecord vs Apex
Use updateRecord when:
Doing simple field updates
You want automatic UI refresh
No complex validation needed
Use Apex when:
Need complex business logic
Updating related records
Require transaction control
When Not to Use updateRecord
While powerful, updateRecord
isn’t always the right choice:
Complex Business Logic: Requires Apex
Batch Updates: For multiple records, consider Apex
Cross-Object Updates: Limited support for complex relationships
Custom Save Behavior: Need fine-grained control over the save process
Best Practices
Refresh UI: Use
refreshApex
if needed.Handle errors: Always show user feedback.
Validate data: Check values before saving.
Handle Errors Gracefully: Provide meaningful feedback to users.
Clean Up Data: Validate and sanitize inputs before updating.
Consider User Context: Remember field-level security and sharing rules.
Optimistic UI: Design for immediate feedback with rollback capability.
Minimize Fields: Only update fields that have actually changed.
- Always Use Schema Imports:
import NAME_FIELD from '@salesforce/schema/Account.Name';
Conclusion
The updateRecord
function in Lightning Data Service provides LWC developers with a powerful, secure, and efficient way to update Salesforce records without writing Apex code. By understanding its capabilities, limitations, and best practices, you can build responsive, data-driven components that provide excellent user experiences while respecting all Salesforce platform protections.
Key takeaways:
Use
updateRecord
for simple to moderately complex single-record updatesLeverage schema imports for maintainable code
Implement robust error handling
Combine with other LDS functions like
getRecord
for complete solutionsKnow when to switch to Apex for more complex requirements
By mastering updateRecord
, you’ll be able to build more efficient Lightning Web Components that handle data updates with minimal code while maximizing platform capabilities.