Hello Trailmixers, today we will discuss the
Promises in LWC i.e. Lightning web components, and what are the use cases of promises in Lightning web components. So let's dive into it.
Let us understand the callback functions before starting with promises.
Callback functions are functions passed as arguments to another function, which will be called in the function it was passed to. The best example of this is
window.setTimeout
. We pass a function to setCallout, which gets called when the timeout is completed.
function myCallbackFunction(){ console.log("in myCallbackFunction"); } window.setTimeout(myCallbackFunction, 2000);
What are promises in JavaScript?
Promises are special objects in JavaScript which represents the
success or failure value of an asynchronous operation.
When you create an asynchronous operation using promise, an object is returned
to which you attach the callbacks for success and failure.
Basically, whatever operation you need to perform, you pass that as function to the promise. When the promise is executed you attach the success and handler function to it.
Let's take an example of file upload. Assume that you want a file to be uploaded in an asynchronous way in the background. And you want to log success messages whenever the operation is completed.
I have created a simple promise method here.
new Promise(resolve => { console.log("File upload started"); window.setTimeout(resolve, 2000); // assume that file takes 2 seconds to upload. }).then((result) => { console.log('File is uploaded'); }) console.log('This block of code continues and get executed before file upload.');
Output for the above code will be:
File upload started This block of code continues and get executed before file upload. File is uploaded // after 2 seconds
Now we will see how we can add the error handler.
new Promise(resolve => { console.log("File upload started"); window.setTimeout(resolve, 2000); }).then((result) => { throw new Error("error"); console.log('File is uploaded'); }).catch(() => { console.log('File upload failed'); // handle error here. })
Output for the above code will be:
File upload started File upload failed // after 2 seconds
States of Promises
There are three main states of promise.
- Pending: The operation is still pending or in progress.
- Fulfilled: Operation is successfully completed.
- Rejected: Operation is failed.
Sometimes the promise is called settled when it is fulfilled or rejected.
Why we use promises?
There are multiple reasons.
- It improves error handling, and you don't need to add custom error handling. No matter if the error is in the async operation or .then() method, it will be passed in .catch().
- It improves the readability of the code.
- We can chain multiple async operations.
- We have better control over the flow of the async operations.
Why Promises are so much important for Lwc?
Promises are everywhere in LWC, this framework heavily uses promises. You are using promises if you are using these things from LWC. All things mentioned below are applications of Promises.
- @wire property or method
- imperative apex methods
- imperative calls to Lightning data service methods.
- loadScript to load external script from the static resource
- loadStyle to load external style from static resources.
If you have ever used imperative calls in lwc, you must have noticed that we
use .then() and .catch() methods to handle success and error.
What are the common use cases?
The most common use case of promise is to load the external style/script in
LWC. See the code used to load third party styles and scripts in the Lightning web component.
Promise.all([ loadScript(this, LIB + '/somelib.js'), loadStyle(this, LIB + '/somestyles.css') ]) .then(() => { // do something when scipt and styles loaded. }) .catch(error => { this.dispatchEvent( new ShowToastEvent({ title: 'Error loading Libs', message: error.message, variant: 'error' }) ); });
Another scenario could be when you want to chain imperative calls to two apex methods. For example
if you have two apex methods
methodA
and methodB
,
now you want to pass the result of methodA
into
methodB
, then you can do it like this.
methodA() .then((result) => ((this.output = result), methodB({ someparam: result }))) .then((result) => (this.output = result));
Calling an API from javascript.
fetch('https://callsomeapi.com/api') .then(response => { // process success }) .catch( error => { // handle error here })
What are the downsides of promises?
One of the biggest downsides of the promises is callback hell. Callback hell is a series of nested calls to the promises. This is very well described in this article Callback hell (Just search for Callback hell). The solution to the callback hell problem is
async-await
which I will cover in some other post some other day.Conclusion
So the conclusion is promises are a very important part of the Lightning web component framework. So here are some advantages of promises, we get more control over asynchronous operations, code becomes readable, and the .then syntax helps us to understand what will run after what.
Random fun fact 😆: "Promises" is a very popular song by Calvin Harris, Sam Smith.
Amazing Post and explanation Rahul thanks !
ReplyDeleteYou are most welcome Shree, thanks for your response. Keep visiting here!!
Deletenice one
ReplyDeleteThank you Fazurulla Ganganapalli!
Deleteis there any way we could hold the remaining code from execution unless promise code is finished i.e. unless it doesn't reaches .then block ??
ReplyDeleteYes use the "async-await" instead of promises, it is like a simplified and advanced version on promises. Check the MDN docs about async-await
Delete