I have read that toPromise()
is being deprecated in RxJS 7 and will be removed in RxJS 8.
I have often used it with async await syntax in angular to handle http calls. Is it considered an anti pattern?
I understand the concept of streams but an http call only emit a single value. I don't get the point of observable for a simple http call. What should I use next? should I fully embrace reactive programming?
but toPromise() is deprecated in recent versions of angular / rxjs.
Promises deal with one asynchronous event at a time, while observables handle a sequence of asynchronous events over a period of time.
How to Convert an Observable to a Promise in Angular? Since the get method of HttpClient returns an observable, we use the toPromise() method to convert the observable to a promise. Since you can convert an observable to a promise, you can make use of the async/await syntax in your Angular code.
The toPromise function lives on the prototype of Observable and is a util method that is used to convert an Observable into a Promise . Inside this function we subscribe to the Observable and resolve the Promise with the last emitted value - attention - when the Observable completes!
RxJS heads up: toPromise is being deprecated. In RxJS 7 toPromise will become deprecated and with RxJS 8 it will be gone! So avoid using toPromise in your future development when possible.
but toPromise () is deprecated in recent versions of angular / rxjs. /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}.
As a replacement to the deprecated toPromise () method, you should use one of the two built in static conversion functions firstValueFrom or lastValueFrom.
Thus, the return type of the lastValueFrom is Promise<T>, just like toPromise () had in RxJS 6. However, you might want to take the first value as it arrives without waiting an Observable to complete, thus you can use firstValueFrom.
Why is this happening?
As mentioned here, these are the main reasons why toPromise
is being deprecated:
One goal was to remove it from the
Observable
prototype and turn it into a standalone util function.The naming of
toPromise
is not the best. Especially when used in combination withawait
it does not read very well:await categories$.toPromise()
vsawait lastValueFrom(categories$)
The type information of
toPromise
is wrong. When the sourceObservable
completed without ever emitting a single value - it resolved withundefined
. It should reject in that case. APromise
is a "promise" that when it resolves a value will be there - and be itundefined
. But when the stream completes without ever emitting a value you can't differentiate between a stream that a emittedundefined
on purpose and a stream that completed without ever emitting anymore
What should you use next?
If you really insist doing it the promise way, lastValueFrom
/firstValueFrom
. Otherwise switching to reactive programming would be the way to go.
Using toPromise
( deprecated ) -
public async loadCategories() {
this.categories = await this.inventoryService
.getCategories()
.toPromise()
}
Using lastValueFrom
( new ) -
import { lastValueFrom } from 'rxjs';
public async loadCategories() {
const categories$ = this.inventoryService.getCategories();
this.categories = await lastValueFrom(categories$);
}
This link should help -
https://indepth.dev/posts/1287/rxjs-heads-up-topromise-is-being-deprecated
firstValueFrom
and lastValueFrom
is definitly a better alternative for many reasons:
await lastValueFrom(data$, {defaultValue: 'Some default value'})
For more about this checkout the video below:
https://www.youtube.com/watch?v=3aeK5SfWBSU
Code example:
Deprecated use:
await this.http.post<boolean>(`/someApi`).toPromise()
.then((value) => {
console.log(`Result: ` + value);
})
New code:
import { firstValueFrom } from 'rxjs';
await firstValueFrom(this.http.post<boolean>(`/someApi`))
.then((value) => {
console.log(`Result: ` + value);
}
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With