• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Using Async/Await In Aurelia

Aurelia 1, Javascript · June 21, 2016

One of the biggest upcoming additions to Javascript (in my opinion) is support for async/await. If you have worked with a language like C# before, then you will immediately know why async/await is fantastic.

Currently async/await is in stage 3 which means it is almost a completed specification. At the time of writing this post, surprisingly Microsoft’s Edge browser is the only browser which has added in support for async/await.

Support alert:
While async/await will soon be standardised into the TC39 specification by the end of 2016 (hopefully) you still need to use a transpiler like Babel to add in support. At the time of writing this, TypeScript lacks support for async/await, so you need to use Babel with it.

Basic Use With A Promise

Remember async/await is made for use with promises mostly, so it doesn’t replace them, but rather enhances them. Instead of chaining a whole bunch of then callbacks, we can write code that looks and works synchronously, but as a whole is actually asynchronous (like a promise).

export class MyViewModel {
    getData() {
        return new Promise((resolve, reject) => {
            // http is either the aurelia-fetch-client or aurelia-http-client
            this.http.get('/mydata').then(data => {
                resolve(data);
            });
        });
    }

    async decorateData() {
        let data = await this.getData();
        // Before the following return is run, the await will halt
        // execution before the function continues

        return {version: 1, data: data};
    }
}

Async/await with Aurelia lifecycle methods

Aurelia allows you to use promises inside of router lifecycle methods like canActivate and activate this means we can also specify them as async functions and use await to halt activation until data is loaded.

export class MyViewModel {
    myData = [];
 
    async activate() {  
        // http is either the aurelia-fetch-client or aurelia-http-client
        let response = await this.http.get('/mydata');

        this.myData = response.content;
    }

}

Error Handling Async/Await

You might notice in the above examples we have no concept of error handling. When working with just promises we generally use .then to capture a successful promise resolution or we use .catch to catch any rejected promises.

The way errors are captured in async functions is similar to how you might catch errors with other bits of code you are running in your application (not promise specific).

export class MyViewModel {
    getData() {
        return new Promise((resolve, reject) => {
            // http is either the aurelia-fetch-client or aurelia-http-client
            this.http.get('/mydata').then(data => {
                resolve(data);
            });
        });
    }

    async decorateData() {
        try {
            let data = await this.getData();
            return {version: 1, data: data};
        } catch(error) {
            console.error(error);
            return null;
        }
    }
}

Multiple Awaits

It isn’t uncommon to potentially have a chain of promises all feeding off one another. In an application I am working on I have one such scenario where pieces are loaded based on previous data, this requires chaining a lot of thennables on my promises and it looks horrendous.

I don’t know what you prefer, but I think it is pretty obvious which one wins out of the two identical examples (one using async/await and one using just promises).

Using Async/Await

The following example is a little contrived, it could actually be simpler, but I wanted to make sure it was obvious what was going on.

export class MyViewModel {
    async doStuff() {
        try {
            let data1 = await this.http.get('/myData/1');
            let data2 = await this.http.get('/myData/2');
            let data3 = await this.http.get('/myData/3');

            this.data1 = data1.content || '';
            this.data2 = data1.content || '';
            this.data3 = data1.content || '';
        } catch(error) {
            console.error(error);
        }
    }
}

Using Promises

export class MyViewModel {
    doStuff() {
        return Promise.all([
            this.http.get('/myData/1'),
            this.http.get('/myData/2'),
            this.http.get('/myData/3')
        ]).then(responses => {
            this.data1 = responses[0].content;
            this.data2 = responses[1].content;
            this.data3 = responses[2].content;
        }).catch(error => {
            console.error(error);
        });
    }
}

Conclusion

With exception of being able to make Aurelia lifecycle methods async, there isn’t anything you need to specifically do to use async/await in your Aurelia application (except needing a transpiler).

Dwayne

Leave a Reply Cancel reply

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mrgoos
Mrgoos
6 years ago

Typescript *does* support it.
In addition, why would you want to load resources synchronously?

0
JB
JB
6 years ago

Might be better to write

const [data1, data2, data3] = await Promise.all([
this.http.get(‘/myData/1’),
this.http.get(‘/myData/2’),
this.http.get(‘/myData/3’),
]);

Much more performant and all the requests are fetched at the same time.

0
pablo
pablo
5 years ago

if you have to fill data from two different service, thats a good reason for sync calls

0

Primary Sidebar

Popular

  • I Joined Truth Social Using a VPN and Editing Some HTML to Bypass the Phone Verification
  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • How To Paginate An Array In Javascript
  • How To Mock uuid In Jest
  • How To Decompile And Compile Android APK's On A Mac Using Apktool
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • Wild Natural Deodorant Review

Recent Comments

  • CJ on Microsoft Modern Wireless Headset Review
  • Dwayne on Microsoft Modern Wireless Headset Review
  • CJ on Microsoft Modern Wireless Headset Review
  • john on Microsoft Modern Wireless Headset Review
  • Dwayne on Why You Should Be Using globalThis Instead of Window In Your Javascript Code

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz