proebuck (60) [Avatar] Offline
#1
MEAP v04
pgs 210-211 (listing 4.15), 212-213

Make the following changes to make refactoring more clear:

Add variable to original listing (but used in both):

const withdraw$ = Rx.Observable.fromEvent(transferButton, 'click');

Original listing with modifications (embedded markup should be removed):
Now uses same Observable as refactored version.
Rx.observable.fromEvent(amountFields, 'keyup')
  .debounceTime(500)
  .map(event => event.target.value)
  .filter(negate(empty))
  .bufferWhen(() => [b]withdraw$[/b])
  .map(amounts => amounts.every(validNum))
  .subscribe(isValid => {
    if (!isValid) {
      completeMsg.innerHTML = 'Entered invalid amounts!';
    } else {
      completeMsg.innerHTML = 'Amounts are valid!';
      performTransfer(...);
    }
  });

Refactored listing with modifications (embedded markup should be removed):
Reverts to positive logic to match original, and adds valid message.
Rx.observable.fromEvent(amountFields, 'keyup')
  .debounceTime(500)
  .map(R.path(['target', 'value'])
  .filter(R.compose(R.not, R.isEmpty))
  .bufferWhen(() => withdraw$)
  .map([b]R.all(R.is(Number))[/b])
  .subscribe([b]isValid[/b] => {
    if (!isValid) {
      completeMsg.innerHTML = 'Entered invalid amounts!';
    } else {
      [b]completeMsg.innerHTML = 'Amounts are valid!';[/b]
      performTransfer(...);
    }
  });


Even as such, wouldn't accessing the performTransfer() arguments
(which are external to the Observable's pipeline) cause purity issue?
Should we add another Observable to perform this function, and subscribe
to it (in the else clause) instead?
331872 (131) [Avatar] Offline
#2
Thanks for the catch on switching to positive logic. I already fixed it.

With respect to:

"Even as such, wouldn't accessing the performTransfer() arguments
(which are external to the Observable's pipeline) cause purity issue? "

I think using other observables in the else clause is really bad practice. You should only combine pure observables and compose them into the source through functions such as mergeMap(), switchMap(), etc as the case may be.

In my opinion, and hopefully this is communicated in the book, is that the observer is in charge of the non-pure operations. We keep our functions pure and the Observable pipeline pure, and let the observers reflect the result of executing this pure code.

Really good observation!
Thanks!