How to switch to another Observable when a source Observable emits but only use latest value
Asked Answered
E

2

6

I have two observables

  • load$ is a stream of load events, emitted on startup or when a reload button is clicked
  • selection$ is a stream of selected list items, emitted when a list item is selected

I'm wondering if there is an operator that lets me (A) get the latest value emitted by selection$ whenever load$ emits, while (B) ignoring the value emitted by load$.

I was able to accomplish (A) by using withLatestFrom but that doesn't satisfy (B) because withLatestFrom does not ignore the source observable.

load$.withLatestFrom(selection$).subscribe(([_, latestSelection) => {
  // _ is not needed and I don't like to write code like this
  // I only need the latest selection
});

I've looked at switchMapTo which satisfies (B) but not (A) without also using first() or take(1).

load$.switchMapTo(selection$.take(1)).subscribe(latestSelection => {
  // I would like to avoid having to use take(1)
});

I'm looking for a hypothetical switchMapToLatestFrom operator.

load$.switchMapToLatestFrom(selection$).subscribe(latestSelection => {
  // switchMapToLatestFrom doesn't exist :(
});

Unfortunately it doesn't exist and I don't like the two other ways that I came up with because it's not immediately obvious why the code contains take(1) or unused arguments.

Are there any other ways to combine two observables so that the new observable emits only the latest value from the second observable whenever the first observable emits?

Endosperm answered 13/7, 2017 at 9:35 Comment(0)
M
11

withLatestFrom takes an optional project function that's passed the values.

You can use it to ignore the value from load$ and emit only the latest selection:

load$
  .withLatestFrom(selection$, (load, selection) => selection)
  .subscribe(selection => {
    // ...
  });
Musquash answered 13/7, 2017 at 10:3 Comment(4)
Thank you, that's exactly what I need. I didn't even realize there was a callback for that.Endosperm
No worries. There are numerous operators in RxJS that take an optional project function, so keep an eye out for them. They can be useful.Musquash
This question comes up quickly on Google, so maybe we can improve it to mention that projections have been removed and the two methods OP suggested are the way to go now (or writing a custom operator for it)?Audrit
@Ingo Yeah, it could do with being updated. Do you have sufficient rep to change it for me?Musquash
O
2

use "sample" operator In your case:

selection$.pipe(sample(load$)).subscribe(
   // the code you want to run
)
Obryant answered 30/6, 2019 at 7:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.