In RxJS 7
toPromise will become deprecated and with RxJS 8 - it will be gone! This is a heads up that tries to prepare you for this breaking change.
What can we use instead?
firstValueFrom - but read on to get the full picture.
In case you have missed it: Currently most of us are enjoying our reactive ride on RxJS 6, but RxJS 7 is already available as a beta version.
Before RxJS 6 and the introduction of
pipe-able operators we could have mistaken
toPromise as an operator, but - it is not.
It can't be used within the
toPromise function lives on the prototype of
Observable and is a util method that is used to convert an
Observable into a
Inside this function we subscribe to the
Observable and resolve the
Promise with the last emitted value - attention - when the Observable completes!
this: Observable<T>: Type declaration of the
thisparameter which is describing the expected type of the implicit
This is a so-called fake parameter - which only exists at compile time - to avoid bugs when you pass a function around and change its
thiscontext without noticing it.
promiseCtoris a Promise constructor - enabling us to use it with different
- The important part: We are then wrapping the the
subscribecall in a
completehandler is called.
When it comes to Angular most of you will be familiar dealing with
Observables when we make HTTP requests using the built in
HttpClient from Angular:
Usage of the "old"
When we don't want to deal with a
Observable in our component then we can currently use
Usage of the "new"
From a functional perspective
lastValueFrom is the function we should go for as replacement of
The change to
await lastValueFrom(categories$) reads pretty nice, don't you think?
Usage of the "new"
When we want to use
firstValueFrom we are not interested in the completion of the stream at all. What we want is its first emitted value, resolve the
Promise with it and unsubscribe from the stream.
This can be useful when we are dealing with a stream that is constantly emitting values and is not completing immediately.
As an example we could think of consuming a stream of events - pushed by the server - e.g using SSE's - Server Sent Events.
InventoryService would use a
EventSource to pass every received message into an
When we are only interested in the first event that is arriving, we can now make use of
At first sight it wasn't totally clear why
toPromise is being deprecated.
Nicholas Jamieson - core team member of RxJS - helped us out here and provided us with some very insightful information:
- One goal was to remove it from the
Observableprototype and turn it into a standalone util function.
- The naming of
toPromiseis not the best.
Especially when used in combination with
awaitit does not read very well:
- The type information of
When the source
Observablecompleted without ever emitting a single value - it resolved with
undefined. It should reject in that case.
Promiseis a "promise" that when it resolves a value will be there - and be it
undefined. But when the stream completes without ever emitting a value you can't differentiate between a stream that a emitted
undefinedon purpose and a stream that completed without ever emitting anymore. More on that here.
toPromise for future development and prefer the use of
toPromise is being deprecated in RxJS 7 and will be removed in RxJS 8.
I tried to avoid the "using Promises is a anti-pattern" topic on purpose here.
Feel free to discuss it in the comments, though.
When would you use
I can think of an API lib that additionally exposes Promises to external partners, who may don't use RxJS at all. It's also useful when using async-await in non-marble tests.
I wish you a great day - thanks for stopping by.