Asynchronous programming is a cornerstone of modern web development, especially in Salesforce Lightning Web Components (LWC), where server calls and data fetching are frequent tasks.
In this blog, we’ll dive deep into async/await in LWC, explore practical scenarios, and demonstrate how to write clean, efficient code.
1. Asynchronous Programming
JavaScript is single-threaded, meaning it processes one operation at a time. Blocking operations (like server calls) would freeze the UI if handled synchronously. Asynchronous code allows non-blocking execution, ensuring smooth user experiences.
In LWC, asynchronous operations include:
- Fetching data from Apex methods.
- Calling external APIs.
- Handling user interactions that require server communication.
2. Promises Recap
Async/await is built on Promises, which represent the eventual result of an asynchronous operation. A Promise can be:
- Pending: Initial state.
- Fulfilled: Operation completed successfully.
- Rejected: Operation failed.
Traditional Promise Syntax:
3. Introduction to Async/Await
Async/await simplifies working with Promises by making asynchronous code look synchronous.
- Async: Declares a function that returns a Promise.
- Await: Pauses execution until the Promise settles (resolves or rejects).
Basic Syntax:
4. Using Async/Await in LWC
4.1 Basic Example: Imperative Apex Call
Call an Apex method imperatively and handle the result.
JavaScript (ContactList.js):
4.2 Error Handling with Try/Catch
Handle errors from Apex methods.
4.4 Chaining Async Operations
Execute dependent operations sequentially.
The fetch API is a modern, flexible way to make HTTP requests in JavaScript. In Lightning Web Components (LWC), you can use fetch to interact with external APIs or custom endpoints. Combining fetch with async/await makes your code cleaner, easier to read, and more maintainable. Below are detailed examples with additional context for each scenario.
Example 1: Basic Fetch with Async/Await
In this example, we fetch a list of posts from a public API (https://jsonplaceholder.typicode.com/posts). This is a common use case for retrieving data from an external service and displaying it in your LWC.
Make sure to add the URL to the Salesforce Trusted URLs.
Go to Setup -> Trusted URLs, click on the ‘New Trusted URL’ button, and add the URL. Please refer to the screenshot below for reference.
import { LightningElement } from 'lwc';
export default class FetchExample extends LightningElement {
data; // Holds the fetched data
error; // Stores any error that occurs during the fetch operation
// connectedCallback is a lifecycle hook that runs when the component is inserted into the DOM
async connectedCallback() {
try {
// Fetch data from the API
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
// Check if the response is successful (status code 200-299)
if (!response.ok) {
throw new Error('Network response was not ok');
}
// Parse the JSON data from the response
this.data = await response.json();
this.error = undefined; // Clear any previous errors
} catch (error) {
// Handle any errors that occur during the fetch operation
this.error = error.message;
this.data = undefined; // Clear any previous data
}
}
}
Template (fetchExample.html)
<template>
<lightning-card title="Fetch Example" icon-name="custom:custom63">
<!-- Display the fetched data if available -->
<template if:true={data}>
<ul>
<template for:each={data} for:item="post">
<li key={post.id}>{post.title}</li>
</template>
</ul>
</template>
<!-- Display an error message if an error occurs -->
<template if:true={error}>
<p class="slds-text-color_error">Error: {error}</p>
</template>
</lightning-card>
</template>
Explanation:
- connectedCallback runs when the component is inserted into the DOM (i.e., when the component is loaded in the browser).
- async keyword: This function is marked as async, which means it will return a promise and allow the use of await within it to handle asynchronous operations in a cleaner way.
- await fetch(): The fetch() function is used to make a network request to the URL ‘https://jsonplaceholder.typicode.com/posts’. The await keyword ensures that JavaScript waits for the fetch operation to complete before continuing.
- If the request is successful, the result (a Response object) will be stored in the response variable.
- If the request isn’t completed (like if the server is slow or the URL doesn’t exist), await will pause execution until a response is received.
Output Screenshot:
Are you preparing for the Salesforce AI Certifications? Check out the Salesforce certification practice set here
FAQs
1. What happens if you forget to use await with an asynchronous function in LWC?
If you forget to use await with an asynchronous function, the function will return a Promise instead of the resolved value. This can lead to unexpected behaviour, such as trying to use a Promise object directly in your code.
2. Can you use await outside of an async function in LWC?
No, you cannot use await outside of an async function. JavaScript will throw a syntax error if you try to do this. The await keyword can only be used inside functions marked as async.
3. How does async/await handle multiple parallel asynchronous calls in LWC?
If you want to run multiple asynchronous calls in parallel, you can use Promise.all with async/await. This ensures that all promises are executed concurrently, and the code waits for all of them to resolve.
4. What happens if an async function in LWC throws an error?
If an async function throws an error, it will reject the Promise it returns. You must handle this error using a try-catch block, or the error will propagate and potentially crash your application.
Also Read – How to Use the getRecord Method in Salesforce LWC
Conclusion
Async/await in LWC simplifies handling asynchronous operations like Apex calls, making code easier to read and maintain. Combine it with try/catch for robust error handling, and use Promise.all for concurrency. Always follow best practices to keep your components efficient and responsive.