Using async-await feature in Angular
Update: With newer version of Angular, we do not need to worry about promise returned from http(). We can still use async-await for other promise based logic though.
In Angular application, we can use Rx.js to leverage power of Observables, Subject, BehaviorSubject etc for writing asynchronous code in elegant way.
ECMAScript Latest Draft (ECMA-262)
If you are from C# background, you might be aware of “async-await” feature supported from C# 5 version.
As per MDN
asyncfunction is called, it returns a
Promise. When the
asyncfunction returns a value, the
Promisewill be resolved with the returned value. When the
asyncfunction throws an exception or some value, the
Promisewill be rejected with the thrown value.
asyncfunction can contain an
awaitexpression, that pauses the execution of the async function and waits for the passed
Promise's resolution, and then resumes the
asyncfunction's execution and returns the resolved value.
In simple term, you shall get an opportunity to write an asynchronous code in synchronous fashion.
Let’s consider a simple example. A function which returns a promise resolving after two seconds and returning value being passed as an argument.
Using promise, we can get the value using “then” callback function.
In above case, console.log() on line 5 shall be executed before console.log() on line 3. That’s the basic nature of promise.
Now let’s see async-await usage.
Few points to note here:
- Line 1 — Function is prefixed with “async” keyword. It is mandatory to use this prefix if your function has “await” keyword.
- Line 2 — We are not calling “.then()” callback function after promise function. Instead we are prefixing function call with “await” keyword. This keyword shall not allow next code block to execute. That means, console.log() at line 3 will get printed only when promise is resolved on line 2 just like a synchronous function call.
- Since we are using Typescript, we need to type cast promise return value to specific type, hence <number> on line 2.
Let’s try to add two numbers using promise based approach.
In real world application, it is very common to end up in nested promise-then code structure (callback hell). With 2 level of nesting we have above code. Imagine 7–8 level of nesting with captured variables and exceptions if any. Scary isn’t it?
Now with async based approach.
Just compare the simplicity of code. Both approach will give us same result but in terms of code readability, maintenance “async-await” outperforms classic promise-then approach.
Consuming Http REST APIs
So far we discussed simple examples. In Angular application, we can get REST data using Http (going to be obsolete soon) or HttpClient service. By default HttpClient class’s “get()”, “put()”, “delete()” and “post()” methods returns “Observable<T>”. This result set can be consumed via “subscribe” method or using “toPromise()” operator from RxJs.
Get HttpClient result using Observable:
I have seen many Angular developers using “subscribe” for getting Http REST data without knowing its difference from “promise”. “subscribe” method is from “Observable” object. Once subscribed, “subscribe” callback shall be executed whenever there is a new data produced by “Observer”. Whereas promise’s “then()” callback handler shall be executed at max once. So until and unless you have requirement to consume recurring data, do not use “subscribe”. Use “toPromise()” instead. If you have noticed examples given on Angular’s official documentation; there is a heavy use of “toPromise”.
Get HttpClient result using toPromise:
Rx.js offers an operator called “toPromise()” which can be used to convert “Observeble<T>” into promise. Once converted it’s “then” block shall get executed whenever there is data.
Get HttpClient result using async-await:
With asyn-await pattern, we do not need neither “subscribe” nor “toPromise”. Code looks very simple and obvious. Line 3 shall be executed once data is fetched from “url”, Observerable<T> is converted to promise and promise is resolved and data is stored in “asyncResult” member variable.
Conditional programming :
Many times the application requires to get data from one url and use condition to fetch next data. Using promise code shall look something like this:
Using async-await code shall look something like this:
You can find complete source code of examples on my GitHub repository.
ng-async-await-demo - Using async-await feature of Typescript to call HttpClient methods
To summaries, async-await feature provides us a better way to write an asynchronous code in Angular application.