Reputation: 718
I need to interlace promises in my app:
protected scroll<T>(path: string, pageSize: number, filter: string, data: T[]): Promise<T[]> {
let promise = new Promise<T[]>(function(resolve, reject) {
this.httpClient
.get<T[]>(this.appConfigService.buildApiUrl(path), { params })
.toPromise<T[]>()
.then(result => {
if (result) {
resolve(data.concat(result));
}
})
.catch(function(e) {
reject(e);
});
});
return promise;
}
My problem is that I receive following message: 'Untyped function calls may not accept type arguments'
How would I solve this?
UPDATE:
I should not have removed the if condition from the example:
if (!filter) {
const params = new HttpParams()
.set('searchText', '')
.set('skip', data.length.toString())
.set('take', pageSize.toString());
const promise = new Promise<T[]>((resolve, reject) => {
this.httpClient
.get<T>(this.appConfigService.buildApiUrl(path), { params })
.toPromise<any>()
.then(result => {
if (result) {
resolve(data.concat(result));
}
resolve(data);
})
.catch(e => reject(e));
});
return promise;
}
// also returning a promise
return this.filter<T>(data, pageSize, filter, path);
Upvotes: 0
Views: 158
Reputation: 1074058
There are a couple of problems there.
The error message is because you're using <T[]>
on get
and toPromise
, which aren't generic functions. Just apply the type T
to result
in the then
handler.
You're falling into the promise creation antipattern. You already have a promise (from this.httpClient
), so you don't need new Promise
.
You're using a traditional function for your new Promise
callback, but then using this
within it as though it were still referring to your class instance. If you were going to keep the new Promise
, you'd want an arrow function instead, so it closes over this
.
Instead (see ***
comments):
protected scroll<T>(path: string, pageSize: number, filter: string, data: T[]): Promise<T[]> {
// *** Return the result of calling `then` on the promise from `toPromise`
return this.httpClient
// *** Don't use <T[]> on `get` and `toPromise`
.get(this.appConfigService.buildApiUrl(path), { params })
.toPromise()
.then((result: T) => { // *** <== Note the `T`
// *** If it's really possible that `result` will be falsy and you don't want that
// to be valid, you can do this:
if (!result) {
throw new Error("appropriate error here");
}
return data.concat(result);
});
}
UPDATE:
I should not have removed the if condition from the example:
It doesn't matter, just put the body of the above into the if
block:
protected scroll<T>(path: string, pageSize: number, filter: string, data: T[]): Promise<T[]> {
if (!filter) {
const params = new HttpParams()
.set('searchText', '')
.set('skip', data.length.toString())
.set('take', pageSize.toString());
return this.httpClient
// *** Don't use <T[]> on `get` and `toPromise`
.get(this.appConfigService.buildApiUrl(path), { params })
.toPromise()
.then((result: T) => { // *** <== Note the `T`
// *** If it's really possible that `result` will be falsy and you don't want that
// to be valid, you can do this:
if (!result) {
throw new Error("appropriate error here");
}
return data.concat(result);
});
}
return this.filter<T>(data, pageSize, filter, path);
}
Upvotes: 1