Async/Await with Angular 2

TypeScript 2.1 was officially announced yesterday, and the biggest feature in this release is probably full support for async/await.

So what’s async/await? It’s a proposed JavaScript feature officially known as Async Functions, but in a nutshell it’s some syntactic sugar that makes working with asynchronous promises look like sequential code.

(If you’re not familiar with Promises to start with check out my ES6 Promises Explained video.)

Let’s dive straight into an example, using Angular and its HTTP Client.

Suppose we have an app where we want to display the current Bitcoin price in US Dollars. Here’s the initial version of this example in Plunker: HTTP request with Promises.

We can fetch the price data in JSON format by making an HTTP request to some API like CoinDesk. Since the request is asynchronous the Angular HTTP Client returns an Observable, that we can convert into a Promise and extract the desired value from the response:

  getPrice(currency: string): Promise<number> {
    return this.http.get(this.currentPriceUrl).toPromise()
      .then(response => response.json().bpi[currency].rate);
  }

Using async/await we can rewrite the same method as:

  async getPrice(currency: string): Promise<number> {
    const response = await this.http.get(this.currentPriceUrl).toPromise();
    return response.json().bpi[currency].rate;
  }

The runnable version is here: HTTP request with Async/Await.

Basically we can use await to assign the result of a promise directly to a variable, without the need to call Promise.then and passing a callback to it. This way our code reads like sequential code, even though there is an asynchronous operation involved.

In order to use the await keyword we need to declare our method async. That’s why async/await are always mentioned in tandem. Note how the value we return in the last line is automatically wrapped in a Promise, because after all our method is still asynchronous, so it cannot return an immediate result.

Be aware that we cannot declare a class constructor as async. So we cannot simply change AppComponent from

  constructor(priceService: PriceService) {
    priceService.getPrice(this.currency)
      .then(price => this.price = price);
  }

to

  async constructor(priceService: PriceService) {
    this.price = await priceService.getPrice(this.currency);
  }

As a workaround we could take advantage of Angular’s lifecycle methods and move our initialisation code to ngOnInit, marking that method as async:

  constructor(private priceService: PriceService) { }

  async ngOnInit() {
    this.price = await this.priceService.getPrice(this.currency);
  }

But in Angular components we could also use the async pipe.

Another thing to be aware of is that async/await only works with Promises, not with RxJS Observables.

So is it worth using async/await in your code? I think it’s very much a matter of personal preference, because at the end of the day it’s just syntactic sugar.

I do like the async/await syntax though.

4 thoughts on “Async/Await with Angular 2

  1. probably it worked earlier, but now has error:

    [ts] Property ‘json’ does not exist on type ‘Object’

    ng –version

    @angular/cli: 1.4.7
    node: 8.5.0
    os: win32 x64
    @angular/animations: 4.4.6
    @angular/cdk: 2.0.0-beta.12
    @angular/common: 4.4.6
    @angular/compiler: 4.4.6
    @angular/core: 4.4.6
    @angular/flex-layout: 2.0.0-rc.1
    @angular/forms: 4.4.6
    @angular/http: 4.4.6
    @angular/material: 2.0.0-beta.12
    @angular/platform-browser: 4.4.6
    @angular/platform-browser-dynamic: 4.4.6
    @angular/router: 4.4.6
    @angular/cli: 1.4.7
    @angular/compiler-cli: 4.4.6
    @angular/language-service: 4.4.6
    typescript: 2.3.4

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s