'.toPromise() and lastValueFrom() in rxjs
I have this observable
createMyRecord(): Observable<myRecord> {
return of(TEMPLATE_DB).pipe(
mergeMap((template) => doTask(template)),
mergeMap(() => EMPTY)
);
}
I call it with
await createMyRecord().toPromise();
.toPromise() is deprecated, so I would like to change the call with lastValueFrom():
await lastValueFrom(createMyRecord());
but I receive the following error:
EmptyError
no elements in sequence
UPDATE: for now, resolved with:
await lastValueFrom(createMyRecord()).catch((err) => {
if (err instanceof EmptyError) {
log.info(OK");
}
});
but is there a better solution?
Solution 1:[1]
Is there a better solution?
Yes and no.
In your case mergeMap(_ => EMPTY)
will ensure that your observable completes without emitting a value. Promises resolve to a value or they error. So the only thing to do here that meets the spec is to throw an error.
A work-around
You can sidestep this by emitting something. For example, here I emit null
after the source completes:
createMyRecord(): Observable<myRecord> {
return of(TEMPLATE_DB).pipe(
mergeMap((template) => doTask(template)),
mergeMap(() => EMPTY),
s => concat(s, of(null as myRecord))
);
}
Now your promise will resolve with a null
once the observable completes successfully.
Something idiomatic
Rather than changing your code, you can change how you call it. This way you don't need to worry about how Observables
and Promises
interact.
Instead of await lastValueFrom(createMyRecord());
write:
createMyRecord().subscribe();
Solution 2:[2]
lastValueFrom
now takes a configuration parameter as its second parameter, and you can specify a default value that will be emitted if the observable is empty:
await rxjs.lastValueFrom(observableThing, {defaultValue: "oh no - empty!"})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | James Moore |