SlyMcFly
SlyMcFly

Reputation: 245

RxJS How to map a stream to the latest of a different stream?

I'm currently using Cycle.js and I'm attempting to get a stream for a text input when a form is submitted. For example:

const textChange$ = DOMSource.select('input').events('change');
const textValueSubmit$ = DOMSource.select('form').events('submit')
    .do(ev => ev.preventDefault());

I think I need to merge the streams at this point but I only care about the latest text value (when the user has submitted the form). What is the appropriate way to handle this situation?

Upvotes: 2

Views: 417

Answers (2)

user3743222
user3743222

Reputation: 18665

Adding to the current answers, you also have the possibility to use withLatestFrom. Note that combineLatest and withLatestFrom semantics differ on subtle points:

  • combineLatest will emit a value whenever one of the combined sources emits a value (so long as each of the source observable sequences has emitted at least one element)
  • withLatestFrom will emit a value only when the combining source emits a value

So you could do for instance :

const textChange$ = DOMSource.select('input').events('change')
  .pluck('target', 'value')
const submit$ = DOMSource.select('form').event('submit')
  .do(ev => ev.preventDefault)
const textValueSubmit$ = submit$.withLatestFrom(textChange$, function (submit, textChange){...});

Even if this does not cover more than your particular use case (here you don't care about the value passed on by the submit event, so as suggested sample also works fine), it is still good to keep those two operators in mind for another similar future use case.

Last thing, does combineLatest really works for you in this case? It seems that you will have a textValueSubmit$ emission every time textChange$ fires. Is that the intended behaviour?

Upvotes: 2

TylorS
TylorS

Reputation: 139

You can also use sample() to avoid creating the extra function, I believe this is the functionality you're looking for

const textChange$ = DOMSource.select('input').events('change')
  .pluck('target', 'value')
const submit$ = DOMSource.select('form').event('submit')
  .do(ev => ev.preventDefault)
const textValueSubmit$ = textChange$.sample(submit$)

Upvotes: 2

Related Questions