Angular 2: Convert Observable to Promise
Solution 1
rxjs7
lastValueFrom(of('foo'));
https://indepth.dev/posts/1287/rxjs-heads-up-topromise-is-being-deprecated
rxjs6
https://github.com/ReactiveX/rxjs/issues/2868#issuecomment-360633707
Don't pipe. It's on the Observable object by default.
Observable.of('foo').toPromise(); // this
rxjs5
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
...
this._APIService.getAssetTypes()
.map(assettypes => {
this._LocalStorageService.setAssetTypes(assettypes);
})
.toPromise()
.catch(err => {
this._LogService.error(JSON.stringify(err));
});
Solution 2
observable can be converted to promise like this:
let promise=observable.toPromise();
Solution 3
you dont really need to do this just do ...
import 'rxjs/add/operator/first';
this.esQueryService.getDocuments$.first().subscribe(() => {
event.enableButtonsCallback();
},
(err: any) => console.error(err)
);
this.getDocuments(query, false);
first() ensures the subscribe block is only called once (after which it will be as if you never subscribed), exactly the same as a promises then()
Solution 4
The proper way to make Observable a Promise, in your case would be following
getAssetTypesPromise() Observable<any> {
return new Promise((resolve, reject) => {
this.getAssetTypes().subscribe((response: any) => {
resolve(response);
}, reject);
});
}
Solution 5
Edit:
.toPromise()
is now deprecated in RxJS 7 (source: https://rxjs.dev/deprecations/to-promise)
New answer:
As a replacement to the deprecated toPromise() method, you should use one of the two built in static conversion functions firstValueFrom or lastValueFrom.
Example:
import { interval, lastValueFrom } from 'rxjs';
import { take } from 'rxjs/operators';
async function execute() {
const source$ = interval(2000).pipe(take(10));
const finalNumber = await lastValueFrom(source$);
console.log(`The final number is ${finalNumber}`);
}
execute();
// Expected output:
// "The final number is 9"
Old answer:
A lot of comments are claiming toPromise
deprecated but as you can see here it's not.
So please juste use toPromise
(RxJs 6) as said:
//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = sample('First Example')
.toPromise()
//output: 'First Example'
.then(result => {
console.log('From Promise:', result);
});
async/await example:
//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = await sample('First Example').toPromise()
// output: 'First Example'
console.log('From Promise:', result);
Read more here.
Note: Otherwise you can use .pipe(take(1)).toPromise
but as said you shouldn't have any problem using above example.
Related videos on Youtube
Dave
Updated on November 24, 2021Comments
-
Dave over 2 years
Q) How do I convert the following observable to a promise so I can call it with
.then(...)
?My method I want to convert to a promise:
this._APIService.getAssetTypes().subscribe( assettypes => { this._LocalStorageService.setAssetTypes(assettypes); }, err => { this._LogService.error(JSON.stringify(err)) }, () => {} );
The service method it calls:
getAssetTypes() { var method = "assettype"; var url = this.apiBaseUrl + method; return this._http.get(url, {}) .map(res => <AssetType[]>res.json()) .map((assettypes) => { assettypes.forEach((assettypes) => { // do anything here you might need.... }); return assettypes; }); }
Thanks!
-
Rohit Sharma over 5 yearsThe Most answers below have
toPromise()
operator, that has been deprecated in RxJS 5.5+
-
-
Dave about 8 yearsGet this error: [ts] Argument of type '(assettypes: any) => void' is not assignable to parameter of type 'PromiseConstructor'. Property 'all' is missing in type '(assettypes: any) => void'. (parameter) assettypes: any
-
Günter Zöchbauer about 8 yearsWhat does
getAssetTypes()
return? -
Dave about 8 yearsan array of interface type AssetType
-
Günter Zöchbauer about 8 yearsIt needs to return an
Observable
for this to work. The code in your question also only works if it returns anObservable
(to callsubscribe(...)
on it) -
Dave about 8 yearsI've updated my question with the service method that is called. thanks.
-
Günter Zöchbauer about 8 yearsOk, it returns an
Observable
. I updated my answer. -
Dave about 8 yearsLet us continue this discussion in chat.
-
Zze about 7 years@GünterZöchbauer has
import 'rxjs/operator/add/toPromise';
been changed to:import 'rxjs/add/operator/toPromise';
? -
Flavien Volken over 6 yearsCorrect, the promise is only resolved at the time the observables completes, using .first() or .take(1) will ensure it's the case after the first emit.
-
Sampath about 6 yearsThe problem here is we cannot use
async/await
pattern. -
Jus10 almost 6 yearstoPromise is deprecated. How would we do this now?
-
KnowledgeSeeker almost 6 yearsIf I conver this to promise I can also catch an error right?
-
Luca C. almost 6 yearsyou can surround with try catch and even user promise.catch()
-
mopo922 over 5 yearsThis can be further simplified to
return new Promise((resolve, reject) => this.getAssetTypes().subscribe(resolve, reject));
-
Mohit Atray over 4 yearsfirst().toPromise() will give you promise and then you can use async/await
-
Emeric over 4 yearsIt's not. Please see my answer.
-
Soroush Falahati over 2 yearsit is deprecated and might be removed in v8. your link is for v6.