skip to Main Content

I have an observable. I’m attempting to convert it to a promise using the lastValueFrom method.

const obs = timer(1000).pipe(
  map(() => `First Value!`),
  startWith('But StartWith this')
);

lastValueFrom(obs).then(console.log);

Outputs:

First Value!

This is not what I was expecting because startWith literally means, start-with. But when I subscribe it, it behaves correctly:

obs.subscribe(console.log);

outputs:

But Start With This
First Value!

Here is the stackblitz.

How to circumvent this issue and get last emitted value as a promise from an observable?


Edit 1: It is interesting that this thing never resolves:

const obs = new Subject().asObservable().pipe(startWith('startWith'));
lastValueFrom(obs).then(console.log);

stackblitz

2

Answers


  1. If I am reading it correctly, then lastValueFrom obs is First Value since you startWith a new value.

    Login or Signup to reply.
  2. In your first example, lastValueFrom makes the value First Value be the last value from your source observable.

    In your second example, nothing is emitted because the observable you create is a so called "cold" observable that never emits a value and therefor never completes. To quote the RxJS docs:

    WARNING: Only use this with observables you know will complete. If the source observable does not complete, you will end up with a promise that is hung up, and potentially all of the state of an async function hanging out in memory. To avoid this situation, look into adding something like timeout, take, takeWhile, or takeUntil amongst others.

    If you add take(1) to the pipe in your second example, it "magically" works. 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search