KEMBAR78
Introduction to RxJS | PDF
RxJS - What is it?
 
Adam Gołąb
Fullstack JS Developer @ Brainhub
Reactive Programming
Reactive programming is an asynchronous programming
paradigm concerned with data streams and the
propagation of change.
 
Think of RxJS as Lodash for events.
 
Developed by Microsoft, in collaboration with a community
of open source developers.
RxJS is a library for composing asynchronous and event-
based programs by using observable sequences. It
provides one core type, the Observable, satellite types
(Observer, Schedulers, Subjects) and operators
inspired by Array#extras (map, filter, reduce,
every, etc) to allow handling asynchronous events as
collections.
Observer
class Observable {
notify() {
for observer in this.observers {
observer.notifyAboutNewState();
}
}
}
Real world example!
Vanilla JS
const button = document.querySelector('button');
button.addEventListener('click', () => console.log('Clicked!'))
RxJS
const button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
.subscribe(() => console.log('Clicked!'));
Purity!
Vanilla JS
let count = 0;
const button = document.querySelector('button');
button.addEventListener('click', () =>
console.log(`Clicked ${++count} times`)
);
RxJS
const button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
.scan(count => count + 1, 0)
.subscribe(count => console.log(`Clicked ${count} times`));
Observable
Lazy Push collections of multiple values. They ll the
missing spot in the following table:
  Single Multiple
Pull Function Iterator
Push Promise Observable
Observable
"just before subscribe"
"got value 1"
"got value 2"
"got value 3"
"just after subscribe"
"got value 4"
"done"
❯
var observable = Rx.Observable.create(
function (observer) {
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(() => {
observer.next(4);
observer.complete();
}, 1000);
}
);
console.log('just before subscribe');
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error(
'something wrong occurred: ' + err
),
complete: () => console.log('done'),
});
console.log('just after subscribe');
Run ClearConsoleJavaScript ▾
HTML CSS JavaScript Console Output HelpJS Bin Save
Executing Observables
The code inside Observable.create(function
subscribe(observer) {...}) represents an
"Observable execution", a lazy computation that only
happens for each Observer that subscribes. The execution
produces multiple values over time, either synchronously or
asynchronously.
 
 
 
Types of values.
There are three types of values an Observable Execution
can deliver:
"Next" noti cation: sends a value such as a Number, a
String, an Object, etc.
"Error" noti cation: sends a JavaScript Error or exception.
"Complete" noti cation: does not send a value.
Executing Observables
"got value 1"
"got value 2"
"got value 3"
"done"
❯
const observable = Rx.Observable.create(
function subscribe(observer) {
try {
observer.next(1);
observer.next(2);
observer.next(3);
observer.complete();
observer.next(4);
} catch (err) {
observer.error(err);
}
}
);
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error(
'something wrong occurred: ' + err
),
complete: () => console.log('done'),
});
Run ClearConsoleJavaScript ▾
HTML CSS JavaScript Console Output HelpJS Bin Save
Subject
A Subject is like an Observable, but can multicast to
many Observers.
Subjects are like EventEmitters they maintain a
registry of many listeners
Subject
"observerA: 1"
"observerB: 1"
"observerA: 2"
"observerB: 2"
❯
const subject = new Rx.Subject();
subject.subscribe({
next: (v) => console.log('observerA: ' + v)
});
subject.subscribe({
next: (v) => console.log('observerB: ' + v)
});
subject.next(1);
subject.next(2);
Run ClearConsoleJavaScript ▾
HTML CSS JavaScript Console Output HelpJS Bin Save
Behavior Subject
One of the variants of Subjects is the
BehaviorSubject, which has a notion of "the current
value". It stores the latest value emitted to its consumers,
and whenever a new Observer subscribes, it will
immediately receive the "current value" from the
BehaviorSubject.
Bahavior Subject
"observerA: 0"
"observerA: 1"
"observerA: 2"
"observerB: 2"
"observerA: 3"
"observerB: 3"
❯
const subject = new Rx.BehaviorSubject(0);
// 0 is the initial value
subject.subscribe({
next: (v) => console.log('observerA: ' + v)
});
subject.next(1);
subject.next(2);
subject.subscribe({
next: (v) => console.log('observerB: ' + v)
});
subject.next(3);
Run ClearConsoleJavaScript ▾
HTML CSS JavaScript Console Output HelpJS Bin Save
Replay Subject
A ReplaySubject is similar to a BehaviorSubject in
that it can send old values to new subscribers, but it can
also record a part of the Observable execution.
Replay Subject
"observerA: 1"
"observerA: 2"
"observerA: 3"
"observerA: 4"
"observerB: 2"
"observerB: 3"
"observerB: 4"
"observerA: 5"
"observerB: 5"
❯
const subject = new Rx.ReplaySubject(3);
// buffer 3 values for new subscribers
subject.subscribe({
next: (v) => console.log('observerA: ' + v)
});
subject.next(1);
subject.next(2);
subject.next(3);
subject.next(4);
subject.subscribe({
next: (v) => console.log('observerB: ' + v)
});
subject.next(5);
Run ClearConsoleJavaScript ▾
HTML CSS JavaScript Console Output HelpJS Bin Save
What are operators?
Operators are methods on the Observable type, such
as .map(...), .filter(...), .merge(...), etc.
When called, they do not change the existing Observable
instance. Instead, they return a new Observable, whose
subscription logic is based on the rst Observable.
Operators
10
20
30
40
❯
function multiplyByTen(input) {
const output = Rx.Observable.create(
function subscribe(observer) {
input.subscribe({
next: (v) => observer.next(10 * v),
error: (err) => observer.error(err),
complete: () => observer.complete()
});
}
);
return output;
}
const input = Rx.Observable.from([1, 2, 3, 4]);
const output = multiplyByTen(input);
output.subscribe(x => console.log(x));
Run ClearConsoleJavaScript ▾
HTML CSS JavaScript Console Output HelpJS Bin Save
Types of Operators
Creation
Transformation
Filtering
Combination
Multicasting
Error Handling
Utility
Operators example
"typed char 1 of
type numeric"
"typed char a of
type alpha"
"typed char @ of
type special"
"typed char Enter
of type special"
❯
const input = document.querySelector('input');
const typedChars = Rx.Observable.fromEvent(input, 'keypress');
const alphaChars = typedChars
.filter(event => /^[A-z]$/.test(event.key))
.map(event => ({ type: 'alpha', value: event.key }));
const numericChars = typedChars
.filter(event => /^d$/.test(event.key))
.map(event => ({ type: 'numeric', value: event.key }));
const specialChars = typedChars
.filter(event => /W|w{2,}/.test(event.key))
.map(event => ({ type: 'special', value: event.key }));
const charsToLog = alphaChars
.merge(numericChars)
.merge(specialChars);
charsToLog.subscribe(key =>
console.log(`typed char ${key.value} of type ${key.type}`)
);
ClearConsoleJavaScript ▾ 1a@
Run with JS
Auto-run JS
HTML CSS JavaScript Console Output HelpJS Bin Save
Useful Resources
http://reactivex.io/rxjs/
http://rxmarbles.com/
http://jaredforsyth.com/rxvision/
Questions?

Introduction to RxJS

  • 1.
  • 2.
      Adam Gołąb Fullstack JSDeveloper @ Brainhub
  • 3.
    Reactive Programming Reactive programmingis an asynchronous programming paradigm concerned with data streams and the propagation of change.
  • 4.
      Think of RxJSas Lodash for events.  
  • 5.
    Developed by Microsoft,in collaboration with a community of open source developers. RxJS is a library for composing asynchronous and event- based programs by using observable sequences. It provides one core type, the Observable, satellite types (Observer, Schedulers, Subjects) and operators inspired by Array#extras (map, filter, reduce, every, etc) to allow handling asynchronous events as collections.
  • 7.
    Observer class Observable { notify(){ for observer in this.observers { observer.notifyAboutNewState(); } } }
  • 8.
    Real world example! VanillaJS const button = document.querySelector('button'); button.addEventListener('click', () => console.log('Clicked!')) RxJS const button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .subscribe(() => console.log('Clicked!'));
  • 9.
    Purity! Vanilla JS let count= 0; const button = document.querySelector('button'); button.addEventListener('click', () => console.log(`Clicked ${++count} times`) ); RxJS const button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .scan(count => count + 1, 0) .subscribe(count => console.log(`Clicked ${count} times`));
  • 11.
    Observable Lazy Push collectionsof multiple values. They ll the missing spot in the following table:   Single Multiple Pull Function Iterator Push Promise Observable
  • 12.
    Observable "just before subscribe" "gotvalue 1" "got value 2" "got value 3" "just after subscribe" "got value 4" "done" ❯ var observable = Rx.Observable.create( function (observer) { observer.next(1); observer.next(2); observer.next(3); setTimeout(() => { observer.next(4); observer.complete(); }, 1000); } ); console.log('just before subscribe'); observable.subscribe({ next: x => console.log('got value ' + x), error: err => console.error( 'something wrong occurred: ' + err ), complete: () => console.log('done'), }); console.log('just after subscribe'); Run ClearConsoleJavaScript ▾ HTML CSS JavaScript Console Output HelpJS Bin Save
  • 13.
    Executing Observables The codeinside Observable.create(function subscribe(observer) {...}) represents an "Observable execution", a lazy computation that only happens for each Observer that subscribes. The execution produces multiple values over time, either synchronously or asynchronously.      
  • 14.
    Types of values. Thereare three types of values an Observable Execution can deliver: "Next" noti cation: sends a value such as a Number, a String, an Object, etc. "Error" noti cation: sends a JavaScript Error or exception. "Complete" noti cation: does not send a value.
  • 15.
    Executing Observables "got value1" "got value 2" "got value 3" "done" ❯ const observable = Rx.Observable.create( function subscribe(observer) { try { observer.next(1); observer.next(2); observer.next(3); observer.complete(); observer.next(4); } catch (err) { observer.error(err); } } ); observable.subscribe({ next: x => console.log('got value ' + x), error: err => console.error( 'something wrong occurred: ' + err ), complete: () => console.log('done'), }); Run ClearConsoleJavaScript ▾ HTML CSS JavaScript Console Output HelpJS Bin Save
  • 16.
    Subject A Subject islike an Observable, but can multicast to many Observers. Subjects are like EventEmitters they maintain a registry of many listeners
  • 17.
    Subject "observerA: 1" "observerB: 1" "observerA:2" "observerB: 2" ❯ const subject = new Rx.Subject(); subject.subscribe({ next: (v) => console.log('observerA: ' + v) }); subject.subscribe({ next: (v) => console.log('observerB: ' + v) }); subject.next(1); subject.next(2); Run ClearConsoleJavaScript ▾ HTML CSS JavaScript Console Output HelpJS Bin Save
  • 18.
    Behavior Subject One ofthe variants of Subjects is the BehaviorSubject, which has a notion of "the current value". It stores the latest value emitted to its consumers, and whenever a new Observer subscribes, it will immediately receive the "current value" from the BehaviorSubject.
  • 19.
    Bahavior Subject "observerA: 0" "observerA:1" "observerA: 2" "observerB: 2" "observerA: 3" "observerB: 3" ❯ const subject = new Rx.BehaviorSubject(0); // 0 is the initial value subject.subscribe({ next: (v) => console.log('observerA: ' + v) }); subject.next(1); subject.next(2); subject.subscribe({ next: (v) => console.log('observerB: ' + v) }); subject.next(3); Run ClearConsoleJavaScript ▾ HTML CSS JavaScript Console Output HelpJS Bin Save
  • 20.
    Replay Subject A ReplaySubjectis similar to a BehaviorSubject in that it can send old values to new subscribers, but it can also record a part of the Observable execution.
  • 21.
    Replay Subject "observerA: 1" "observerA:2" "observerA: 3" "observerA: 4" "observerB: 2" "observerB: 3" "observerB: 4" "observerA: 5" "observerB: 5" ❯ const subject = new Rx.ReplaySubject(3); // buffer 3 values for new subscribers subject.subscribe({ next: (v) => console.log('observerA: ' + v) }); subject.next(1); subject.next(2); subject.next(3); subject.next(4); subject.subscribe({ next: (v) => console.log('observerB: ' + v) }); subject.next(5); Run ClearConsoleJavaScript ▾ HTML CSS JavaScript Console Output HelpJS Bin Save
  • 23.
    What are operators? Operatorsare methods on the Observable type, such as .map(...), .filter(...), .merge(...), etc. When called, they do not change the existing Observable instance. Instead, they return a new Observable, whose subscription logic is based on the rst Observable.
  • 24.
    Operators 10 20 30 40 ❯ function multiplyByTen(input) { constoutput = Rx.Observable.create( function subscribe(observer) { input.subscribe({ next: (v) => observer.next(10 * v), error: (err) => observer.error(err), complete: () => observer.complete() }); } ); return output; } const input = Rx.Observable.from([1, 2, 3, 4]); const output = multiplyByTen(input); output.subscribe(x => console.log(x)); Run ClearConsoleJavaScript ▾ HTML CSS JavaScript Console Output HelpJS Bin Save
  • 25.
  • 26.
    Operators example "typed char1 of type numeric" "typed char a of type alpha" "typed char @ of type special" "typed char Enter of type special" ❯ const input = document.querySelector('input'); const typedChars = Rx.Observable.fromEvent(input, 'keypress'); const alphaChars = typedChars .filter(event => /^[A-z]$/.test(event.key)) .map(event => ({ type: 'alpha', value: event.key })); const numericChars = typedChars .filter(event => /^d$/.test(event.key)) .map(event => ({ type: 'numeric', value: event.key })); const specialChars = typedChars .filter(event => /W|w{2,}/.test(event.key)) .map(event => ({ type: 'special', value: event.key })); const charsToLog = alphaChars .merge(numericChars) .merge(specialChars); charsToLog.subscribe(key => console.log(`typed char ${key.value} of type ${key.type}`) ); ClearConsoleJavaScript ▾ 1a@ Run with JS Auto-run JS HTML CSS JavaScript Console Output HelpJS Bin Save
  • 27.
  • 28.