RxJS-handson
RxJS-handson
bufferCount
/*
bufferCount also takes second argument, when to start the next buffer
for instance, if we have a bufferCount of 3 but second argument (startBufferEvery) of 1:
1st interval value:
buffer 1: [0]
2nd interval value:
buffer 1: [0,1]
buffer 2: [1]
3rd interval value:
buffer 1: [0,1,2] Buffer of 3, emit buffer
buffer 2: [1,2]
buffer 3: [2]
4th interval value:
buffer 2: [1,2,3] Buffer of 3, emit buffer
buffer 3: [2, 3]
buffer 4: [3]
*/
const bufferEveryOne = myInterval.bufferCount(3,1);
//Print values to console
const secondSubscribe = bufferEveryOne.subscribe(val => console.log('Start Buffer Every 1:',
val))
bufferTime
/*
bufferTime also takes second argument, when to start the next buffer (time in ms)
for instance, if we have a bufferTime of 2 seconds but second argument
(bufferCreationInterval) of 1 second:
ex. output: [0,1,2]...[1,2,3,4,5]...[3,4,5,6,7]
*/
const bufferTimeTwo = myInterval.bufferTime(2000,1000);
//Print values to console
const secondSubscribe = bufferTimeTwo.subscribe(val => console.log('Start Buffer Every 1s:',
val));
bufferToggle
bufferWhen
combineAll
combineLatest
//when one timer emits, emit the latest values from each timer as an array
const combined = Rx.Observable
.combineLatest(
timerOne,
timerTwo,
timerThree
);
concat
#####signature: concat(observables: ...*): Observable The gist: Like the line at an ATM, the
next transaction (subscription) won't start until the previous completes...
(demo | official docs)
//emits 1,2,3
const sourceOne = Rx.Observable.of(1,2,3);
//emits 4,5,6
const sourceTwo = Rx.Observable.of(4,5,6);
//emit values from sourceOne, when complete, subscribe to sourceTwo
const concatSource = sourceOne.concat(sourceTwo);
//output: 1,2,3,4,5,6
const subscribe = concatSource.subscribe(val => console.log('Example 1: Basic concat:',
val));
//delay 3 seconds then emit
const delayedSourceOne = sourceOne.delay(3000);
//sourceTwo waits on sourceOne to complete before subscribing
const concatDelayedSource = delayedSourceOne.concat(sourceTwo);
//output: 1,2,3,4,5,6
const subscribeDelayed = concatDelayedSource.subscribe(val => console.log('Example 2: Delayed
source one:', val));
concatAll
concatMap
//result of first param passed to second param selector function before being returned
const exampleWithSelector = source.concatMap(val => examplePromise(val), result => `${result}
w/ selector!`);
//output: 'Example w/ Selector: 'Hello w/ Selector', Example w/ Selector: 'Goodbye w/
Selector'
const subscribeThree = exampleWithSelector
//delay for logging clarity
.delay(2000)
.subscribe(val => console.log('Example w/ Selector:', val));
concatMapTo
*/
const subscribeTwo = exampleTwo.subscribe(val => console.log(val));
count
#####signature: count(predicate: function): Observable The gist: Count values emitted from
source until complete, optionally base count on predicate...
(demo | official docs)
debounce
debounceTime
//log values
const subscribe = debouncedInput.subscribe(val => {
console.log(`Debounced Input: ${val}`);
});
defaultIfEmpty
//empty observable
const emptyTwo = Rx.Observable.empty();
//emit 'Observable.empty()!' when empty, else any values from source
const exampleTwo = emptyTwo.defaultIfEmpty('Observable.empty()!');
//output: 'Observable.empty()!'
const subscribe = exampleTwo.subscribe(val => console.log(val));
delay
delayWhen
dematerialize
distinctUntilChanged
#####signature: distinctUntilChanged(compare: function): Observable The gist: Only emit
when the next value is different then the last...
(demo | official docs)
do
every
#####signature: every(predicate: function, thisArg: any): Observable The gist: Does every
emitted item pass a condition?...
(demo | official docs)
//emit 5 values
const source = Rx.Observable.of(1,2,3,4,5);
const example = source
//is every value even?
.every(val => val % 2 === 0)
//output: false
const subscribe = example.subscribe(val => console.log(val));
//emit 5 values
const allEvens = Rx.Observable.of(2,4,6,8,10);
const exampleTwo = allEvens
//is every value even?
.every(val => val % 2 === 0);
//output: true
const subscribeTwo = exampleTwo.subscribe(val => console.log(val));
expand
filter
#####signature: filter(select: Function, thisArg: any): Observable The gist: Only return
values that pass the provided condition...
(demo | official docs)
//emit (1,2,3,4,5)
const source = Rx.Observable.from([1,2,3,4,5]);
//filter out non-even numbers
const example = source.filter(num => num % 2 === 0);
//output: "Even number: 2", "Even number: 4"
const subscribe = example.subscribe(val => console.log(`Even number: ${val}`));
first
#####signature: first(predicate: function, select: function) The gist: Emit the first value,
or the first to pass condition...
(demo | official docs)
groupBy
const people = [{name: 'Sue', age:25},{name: 'Joe', age: 30},{name: 'Frank', age: 25}, {name:
'Sarah', age: 35}];
//emit each person
const source = Rx.Observable.from(people);
//group by age
const example = source
.groupBy(person => person.age)
//return as array of each group
.flatMap(group => group.reduce((acc, curr) => [...acc, ...curr], []))
/*
output:
[{age: 25, name: "Sue"},{age: 25, name: "Frank"}]
[{age: 30, name: "Joe"}]
[{age: 35, name: "Sarah"}]
*/
const subscribe = example.subscribe(val => console.log(val));
ignoreElements
#####signature: ignoreElements(): Observable The gist: Ignore everything but complete and
error...
(demo | official docs)
last
#####signature: last(predicate: function): Observable The gist: Emit last item or last to
pass test...
(demo | official docs)
let
#####signature: let(function): Observable The gist: let me have the whole observable...
(demo | official docs)
//let provides flexibility to add multiple operators to source observable then return
const letTestThree = myObservableArray
.map(val => val + 1)
.let(obs => obs
.map(val => val + 2)
//also, just return evens
.filter(val => val % 2 === 0)
)
.subscribe(val => console.log('let WITH MULTIPLE OPERATORS: ', val));
map
#####signature: map(project: Function, thisArg: any): Observable The gist: Apply projection
to each element...
(demo | official docs)
//emit (1,2,3,4,5)
const source = Rx.Observable.from([1,2,3,4,5]);
//add 10 to each value
const example = source.map(val => val + 10);
//output: 11,12,13,14,15
const subscribe = example.subscribe(val => console.log(val));
//emit ({name: 'Joe', age: 30}, {name: 'Frank', age: 20},{name: 'Ryan', age: 50})
const sourceTwo = Rx.Observable.from([{name: 'Joe', age: 30}, {name: 'Frank', age: 20},{name:
'Ryan', age: 50}]);
//grab each persons name
const exampleTwo = sourceTwo.map(person => person.name);
//output: "Joe","Frank","Ryan"
const subscribe = exampleTwo.subscribe(val => console.log(val));
mapTo
#####signature: mapTo(value: any): Observable The gist: Map to a constant value every
time...
(demo | official docs)
merge
#####signature: merge(input: Observable): Observable The gist: Squish outputs from multiple
observables into a single source...
(demo | official docs)
mergeMap
//emit 'Hello'
const source = Rx.Observable.of('Hello');
//map to inner observable and flatten
const example = source.mergeMap(val => Rx.Observable.of(`${val} World!`));
//output: 'Hello World!'
const subscribe = example.subscribe(val => console.log(val));
partition
pluck
publish
/*
source will not emit values until connect() is called
output: (after 5s)
"Do Something!"
"Subscriber One: 0"
"Subscriber Two: 0"
"Do Something!"
"Subscriber One: 1"
"Subscriber Two: 1"
*/
const subscribe = example.subscribe(val => console.log(`Subscriber One: ${val}`));
const subscribeTwo = example.subscribe(val => console.log(`Subscriber Two: ${val}`));
race
#####signature: race(): Observable The gist: Take the first observable to emit...
(demo | official docs)
repeat
#####signature: repeat(scheduler: Scheduler, count: number): Observable The gist: Repeat
source specified number of times...
(demo | official docs)
retry
#####signature: retry(number: number): Observable The gist: Retry specified number of times
on error...
(demo | official docs)
retryWhen
sample
#####signature: sample(sampler: Observable): Observable The gist: Sample from source when
supplied observable emits...
(demo | official docs)
scan
#####signature: scan(accumulator: function, seed: any): Observable The gist: Reduce over
time...
(demo | official docs)
share
single
#####signature: single(a: Function): Observable The gist: Emit single item that matches
condition...
(demo | official docs)
//emit (1,2,3,4,5)
const source = Rx.Observable.from([1,2,3,4,5]);
//emit one item that matches predicate
const example = source.single(val => val === 4);
//output: 4
const subscribe = example.subscribe(val => console.log(val));
skip
#####signature: skip(the: Number): Observable The gist: Skip a specified number of emitted
items...
(demo | official docs)
//emit every 1s
const source = Rx.Observable.interval(1000);
//skip the first 5 emitted values
const example = source.skip(5);
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));
skipUntil
#####signature: skipUntil(the: Observable): Observable The gist: Skip emitted items from
source until inner observable emits...
(demo | official docs)
//emit every 1s
const source = Rx.Observable.interval(1000);
//skip emitted values from source until inner observable emits (6s)
const example = source.skipUntil(Rx.Observable.timer(6000));
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));
skipWhile
#####signature: skipWhile(predicate: Function): Observable The gist: Skip emitted items
from source until provided expression is false...
(demo | official docs)
//emit every 1s
const source = Rx.Observable.interval(1000);
//skip emitted values from source while value is less than 5
const example = source.skipWhile(val => val < 5);
//output: 5...6...7...8........
const subscribe = example.subscribe(val => console.log(val));
startWith
#####signature: startWith(an: Values): Observable The gist: Emit specified item first...
(demo | official docs)
//emit (1,2,3)
const source = Rx.Observable.of(1,2,3);
//start with 0
const example = source.startWith(0);
//output: 0,1,2,3
const subscribe = example.subscribe(val => console.log(val));
switchMap
#####signature: switchMap(a: Observable): Observable The gist: When source emits, switch
to and emit values emitted from latest inner observable
(demo | official docs)
window
windowCount
//emit every 1s
const source = Rx.Observable.interval(1000);
const example = source
//start new window every 4 emitted values
.windowCount(4)
.do(() => console.log('NEW WINDOW!'))
windowTime
windowToggle
windowWhen
//emit every 5s
const source = Rx.Observable.interval(5000);
//emit every 1s
const secondSource = Rx.Observable.interval(1000);
const example = source
.withLatestFrom(secondSource)
.map(([first, second]) => {
return `First Source (5s): ${first} Second Source (1s): ${second}`;
});
/*
"First Source (5s): 0 Second Source (1s): 4"
"First Source (5s): 1 Second Source (1s): 9"
"First Source (5s): 2 Second Source (1s): 14"
...
*/
const subscribe = example.subscribe(val => console.log(val));
//withLatestFrom slower than source
const exampleTwo = secondSource
//both sources must emit at least 1 value (5s) before emitting
.withLatestFrom(source)
.map(([first, second]) => {
return `Source (1s): ${first} Latest From (5s): ${second}`;
});
/*
"Source (1s): 4 Latest From (5s): 0"
"Source (1s): 5 Latest From (5s): 0"
"Source (1s): 6 Latest From (5s): 0"
...
*/
const subscribeTwo = exampleTwo.subscribe(val => console.log(val));
zip
#####signature: zip(observables: *): Observable The gist: After all observables emit, emit
values as an array...
(demo | official docs)
//emit every 1s
const interval = Rx.Observable.interval(1000);
//when one observable completes no more values will be emitted
const exampleTwo = Rx.Observable
.zip(
interval,
interval.take(2)
);
//output: [0,0]...[1,1]
const subscribe = exampleTwo.subscribe(val => console.log(val));