I am attempting to use async/await
in an angular 1.5.5
project.
Given this service method
getDocumentTypes(): angular.IPromise<DocumentType[]> {
var url = "api/document/types";
this.$log.log(url);
return this.$http.get(url).then(_ => _.data);
}
I am attempting to create an async / await
version of the method.
async getDocTypes(): angular.IPromise<DocumentType[]> {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}}
Intellisense shows an error:
TS1055
Type 'angular.IPromise' is not a valid async function return type inES5/ES3
because it does not refer to a Promise-patible constructor value.
Is there a correct way to use an angular promise in typescript 2.1 with async
/ await
?
I am attempting to use async/await
in an angular 1.5.5
project.
Given this service method
getDocumentTypes(): angular.IPromise<DocumentType[]> {
var url = "api/document/types";
this.$log.log(url);
return this.$http.get(url).then(_ => _.data);
}
I am attempting to create an async / await
version of the method.
async getDocTypes(): angular.IPromise<DocumentType[]> {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}}
Intellisense shows an error:
TS1055
Type 'angular.IPromise' is not a valid async function return type inES5/ES3
because it does not refer to a Promise-patible constructor value.
Is there a correct way to use an angular promise in typescript 2.1 with async
/ await
?
- where are the type annotations for angular ing from? could that be updated? – Daniel A. White Commented Dec 15, 2016 at 14:44
- updating the typings has proved to be a problem as well. stackoverflow./questions/41216046/… – Jim Commented Dec 20, 2016 at 6:17
-
I have successfully updated the typings using
npm i @types/angular
. There is an interface in the 2.1 lib.d.ts calledPromiseLike<T>
but it's not clear how it might be used. – Jim Commented Dec 22, 2016 at 4:47
3 Answers
Reset to default 2You may need to just use Promise directly:
async getDocTypes(): Promise<DocumentType[]> {
}}
The typescript 2+ generated code, will fall outside of the angular digest cycle, and the ponent / directive will not update the view / model correctly.
async / await can work in angularjs 1.5
if the $q
scheduler is swapped out with Bluebird
promises.
By adding the following to app.ts
export class Module {
app: ng.IModule;
constructor(name: string, modules: Array<string>) {
this.app = module(name, modules);
}
}
function trackDigests(app) {
app.run(["$rootScope",$rootScope => {
Promise.setScheduler(cb => {
$rootScope.$evalAsync(cb);
});
}]);
}
export var app: ng.IModule = new Module("app", []).app;
trackDigests(app);
The regular $q
scheduler is swapped out.
Code like this works out of the box!
async $onInit() {
this.start();
try {
var key = await this.powerService.getKey(this._apiKey.partyAccountNumber);
var sites = await this.powerService.loadSites(this._apiKey.partyAccountNumber);
await this.showSummary(sites);
this.stop(true);
} catch (error) {
this.$log.error(error);
this.stop(false);
}
}
You can return Promise
or ng.IPromse
from your service methods, as they are interchangable.
export interface IPowerService {
setKey(key: pa.PowerApi): ng.IPromise<dm.ClientSite[]>;
getKey(partyAccountNumber: string): Promise<pa.PowerApi>;
}
By using the above trackDigests
in the test harness, unit tests will also work with async / await
In my case, I added the following to my webpack.test.js
to enable async/await
to function the same way with karma tests.
plugins: [
new webpack.ProvidePlugin({
Promise: 'bluebird'
})
],
disclaimer: this answer works in 2018 with TS 3.2.2
. I am not sure they are similar in 2.1.
currently there are piler options allowing libraries to be added to the pilation. To use async/await you have the next options:
- mand line:
--target ES6 --lib es2015.generator
. - Config file:
{ "pilerOptions": { "target": "es5", "lib": ["es2015.generator"] ... } ... }