sainture
3/13/2018 - 5:26 AM

pipeable operators

previously called lettable operators

// With RxJS 5.5 came the introduction of pipeable, or “lettable”, operators

// e.g. you can use clicks$.pipe(debounce(250)) instead of chaining operators directly on the 
// Observable like this clicks$.debounce(250)

// Those operators are pure functions that can be used as standalone operators instead
// of methods on an observable.

// They’re lightweight, will make your code easily re-usable and can decrease your overall build size.

// Previously, we used to do the following for things like filter , map, scan

import { from } from 'rxjs/observable/from';

const source$ = from([1, 2, 3, 4, 5, 6, 7, 8, 9]);

source$
  .filter(x => x % 2)
  .map(x => x * 2)
  .scan((acc, next) => acc + next, 0)
  .startWith(0)
  .subscribe(console.log)
  

// Whereas now all those operators are available as pure functions under rxjs/operators.
// What does that mean? That means it’s really easy to build custom operators !
// Let’s say I know that I’m going to re-use this filter, well, with lettable operators I can just do this:

import { filter, map, reduce } from 'rxjs/operators';

const filterOutEvens = filter(x => x % 2);
const sum = reduce((acc, next) => acc + next, 0);
const doubleBy = x => map(value => value * x);

// So now we want a way to use those operators, how could we do that?
source$.let(filterOutEvens).subscribe(x => console.log(x)); // [1, 3, 5, 7, 9]

// And if we want to chain multiple lettable operators we can keep dot chaining:
source$
  .let(filterOutEvens)
  .let(doubleBy(2))
  .let(sum)
  .subscribe(x => console.log(x)); // 50
  
  
// pipe method
// All this looks cool but its still very verbose. Well, thanks to RxJS 5.5 observables now have a pipe
// method available on the instances allowing you to clean up the code above by calling pipe with all
// our pure functions operators:

source$.pipe(
  filterOutEvens, 
  doubleBy(2), 
  sum)
  .subscribe(console.log); // 50
  
  
/*
What does that mean? That means that any operators you previously used on the instance of observable are
available as pure functions under rxjs/operators. This makes building a composition of operators or 
re-using operators becomes really easy
*/

// but what if I want to re-use this logic in different places ?
const complicatedLogic = pipe(
  filterOutEvens,
  doubleBy(2),
  sum
);

source$.let(complicatedLogic).subscribe(x => console.log(x)); // 50

// Meaning we can easily compose a bunch of pure function operators and pass them as a single 
// operator to an observable!