Salesforce introduced Lightning platform a couple of years back and it’s been evolving and getting better with every release so far. Developers who used to work with Visualforce pages have started moving to the new Lightning component framework because it’s more flexible.
Lightning is a JS-first platform based out of aura, and uses JS Controllers and Helpers to display and retrieve data from Salesforce. Because Lightning components can interact with server side Apex controllers using asynchronous calls, they generally need a callback function to handle the response.
For example, say we have an apex controller “LightningCtrl” with a method getCurrentUser that queries the current logged in user’s detail and returns it.
To call the same thing from an sLightning component, you need have a lightning controller which looks something like this:
So the JS controller calls the Apex controller methods to get the data back and then sets the data in a variable. So far, pretty simple.
But what happens if we had another call along with it?
As we add more dependent calls the nesting increases and makes the code very hard to read. With a lot of calls, it can get pretty ugly and unmanageable.
So what’s the solution ? Promises !
Promises provides a simpler alternative for executing, composing, and managing asynchronous operations when compared to traditional callback-based approaches. It also allows you to handle asynchronous errors using an approach similar to synchronous try/catch. It makes the code much cleaner and easier to read and manage.
So now, let’s reimagine the above controller code in Promises. First some housekeeping and restructuring to make sure we are reusing the code.
And now we can rewrite the controller using the above refactored helper
Pretty organised isn’t it ?
What did we do here ?
We essentially moved our code that calls the controller into a new function, to avoid repetitive code.
Now let’s take a deep dive into the new “call” method.
The call method uses Promises instead of the callbacks. A promise can be either rejected or fulfilled / resolved. So whenever we make a call to a server or the apex controller, it can be successful in which case it will be resolved, else it fails and will be rejected, with the reason why it failed.
So the “call” method takes in the action to be called and the optional params if any are accepted by the controller method. If the status is success it calls resolve. Otherwise it calls reject.
To summarize, the call method should invoke (something that usually takes time) and then call resolve or reject to change the state of the corresponding promise object.
Calling the promises
The primary API for a promise is its “then” method, which registers callbacks to receive either the eventual value or the reason why the promise cannot be fulfilled. In the above code snippets we have a handler to handle the different state. For successes we are setting the user variable and for errors we are displaying an error message.
What if an error occurs while performing an asynchronous operation? We can handle it by using the error handler of the “then”, or we can use catch which is very similar to try / catch.
Let’s rewrite the code using catch:
Pretty straightforward isn’t it? We add a catch handler which handles / catches the error.
So now the fun part, how do we handle nested calls ?
In promises we don’t need nested callback. Instead we use “then” to chain different promises, like so:
To sum up, Promises makes async code much more organized and easier to read. It also offers an easier way to handle errors and exceptions, without deep nested code. This should help you write more readable code.
Happy Coding !