Back to Blog Home
← all posts

Use async/await with TypeScript in NativeScript today

September 30, 2016 — by Panayot Cankov

Async/await allows developers to write asynchronous code as if they were synchronous. Support for async/await in TypeScript is available when targeting ES6 but down compiling to ES5 is yet to be implemented. So long the story can be summarized in TypeScript -> ES6 -> Babel -> ES5. And this was the official story from the TypeScript team.

Recently commits on down-compiling TypeScript to ES5 were merged in the TypeScript master, making them available in typescript@next, this way the Babel step is avoided and TypeScript compiles directly to ES5.

We will make an app and install the @next that’s all about this:

export async function navigatingTo(args) {
   let page = args.object.page;
   let issues = await http.getJSON(nIssuesUrl);
   page.bindingContext = issues;
}


Populating up a github issues list:

IssuesList

Async/await down compiling to ES5 was recently merged in the TypeScript master, and is now available within the TypeScript @next version.

If you are inpatient you can jump directly to the example app here: https://github.com/PanayotCankov/NativeScript-AsyncAwait/

Make an app

To use in {N} app, just make your new TypeScript enabled app:

tns create IssuesList --template typescript
cd IssuesList


Install locally the nightly build - typescript@next:

npm install typescript@next --save-dev


Then open VSCode:

code .


If VSCode asks you to use the TypeScript installed in the workspace - go yes, currently if you don't, it will use an official TS version, and may complain about async being supported when targeting ES6.

Show me the helpers

{N} ships commonjs modules and emitting helpers in every module is undesirable. {N} also provides __extend already, that helps extending native Objective-C and Java classes.

We will generate a single file with the required helpers for async/await. Create an app/helpers.ts file with the following typescript:

export async function test() {}


Then run the @next tsc:

./node_modules/.bin/tsc app/helpers.ts --target es5


Once the app/helpers.js is ready, delete the app/helpers.ts. Also open the .js file and edit:

var __awaiter = /* ... */
var __generator = /* ... */


to:

global.__awaiter = /* ... */
global.__generator = /* ... */


You may as well delete the test() function.

The {N} entry point is the app/app.js and we'll make sure to import the helpers there:

require('./helpers');
import * as app from 'application';
app.start({ moduleName: 'main-page' });


Use

Now we can make a good use of the async/await in our app at app/main-page.ts:

import * as http from "http";

const nIssuesUrl = "https://api.github.com/repos/NativeScript/NativeScript/issues";

export async function navigatingTo(args) {
 let page = args.object.page;
 let issues = await http.getJSON(nIssuesUrl);
 console.log("issues: " + issues);
 page.bindingContext = issues;
}


All we have to do now is template these github issues in app/main-page.xml:

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
 <ListView items="{{ $value }}">
   <ListView.itemTemplate>
     <GridLayout columns="42, *" height="42">
       <Image src="{{ user.avatar_url }}"
           width="24" height="24"
           horizontalAlignmnet="center" verticalAlignment="center"
           borderColor="gray" borderWidth="1" borderRadius="12" />
       <Label col="1" text="{{ title }}" verticalAlignment="center" textAlignment="left" />
     </GridLayout>
   </ListView.itemTemplate>
 </ListView>
</Page>


Run

We can finally run the app:

tns run ios


The NativeScript TypeScript plugin uses TypeScript compiler installed as dependency (similar to the way VSCode got it working) so it will automatically pick the latest version.

Now the down-compiled code will work in our ES5 environments. Keep in mind the iOS and Android runtimes use custom builds on JavaScriptCore and V8 so new ES features get adopted quickly, we may see TypeScript -> ES6 ready quite soon.

Regards,