RxJS
Observables
REACTIVE EXTENSIONS LIBRARY FOR JAVASCRIPT
RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code.
npm install --save rxjsimport { Observable } from 'rxjs';1. Install via npm
2. Import into your code
Iterable...
import { Observable } from 'rxjs';
const source = Observable.create(observer => {
let count = 0;
const timer = setInterval(() => {
observer.next(count);
count++;
}, 500);
return () => clearInterval(timer);
});
source.subscribe(
value => { console.log('next: ', value); },
error => { console.log('error: ', error); },
() => { console.log('complete'); }
);
import { Observable } from 'rxjs';
promise = new Promise(resolve => {
console.log('Create Promise');
resolve('promise-result')
});
source = Observable.create(observer => {
console.log('Create Observable');
observer.next('observable-result');
});import { Observable } from 'rxjs';
promise = new Promise(resolve => {
console.log('Create Promise');
resolve('promise-result')
});
source = Observable.create(observer => {
console.log('Create Observable');
observer.next('observable-result');
});
promise.then(data => console.log('handle:', data));
source.subscribe(value => console.log('handle:', value));import { Observable } from 'rxjs';
promise = new Promise(resolve => {
console.log('Create Promise');
resolve('promise-result')
});
source = Observable.create(observer => {
console.log('Create Observable');
observer.next('observable-result');
});
promise.then(data => console.log('handle:', data));
source.subscribe(value => console.log('handle:', value));
promise.then(data => console.log('handle:', data));
source.subscribe(value => console.log('handle:', value));import { of } from 'rxjs';
const source = of({message: 'any Object'});
const subscription = source.subscribe(
value => console.log('next: ', value),
error => console.error('error: ', error),
() => console.log('complete')
);import { from } from 'rxjs';
const source = from([10, 20, 30]);
const subscription = source.subscribe(
value => console.log('next: ', value),
error => console.error('error: ', error),
() => console.log('complete')
);import { range } from 'rxjs';
source = range(10, 4);import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
source = interval(2000)
.pipe(
take(2)
);import { throwError } from 'rxjs';
source = throwError('Damn!');import { EMPTY } from 'rxjs';
import { defaultIfEmpty } from 'rxjs/operators';
source = EMPTY.pipe(
defaultIfEmpty('any default value')
);import { NEVER } from 'rxjs';
source = NEVER;import { throwError, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
const source = throwError('Whoops!');
const subscription = source.pipe(
catchError(err => {
console.log('catch:', err);
return of('safety result');
})
)
.subscribe(
value => console.log('next: ', value),
error => console.error('error: ', error),
() => console.log('complete')
);import { Observable } from 'rxjs';
import { retry } from 'rxjs/operators';
const source = Observable.create(observer => {
console.log('Next attempt');
observer.error('Whoops!');
});
const subscription = source.pipe(
retry(2)
)
.subscribe(
value => console.log('next: ', value),
error => console.error('error: ', error),
() => console.log('complete')
);import { Observable, throwError } from 'rxjs';
import { retryWhen } from 'rxjs/operators';
let flag = true;
const source = Observable.create(observer => {
console.log('Fake server call');
if (flag) {
observer.error('Damn');
flag = false;
} else {
observer.next('success');
}
});
const obs = new Observable(observer => {
console.log('let wait a second');
setTimeout(() => observer.next('any'), 1000);
});
const subscription = source.pipe( retryWhen(err$ => obs) )
.subscribe( value => console.log('next:', value) );import { Observable, throwError } from 'rxjs';
import { retryWhen } from 'rxjs/operators';
source = Observable.create(observer => {
console.log('Attempt');
observer.error('Whoops!');
});
planB = of('Nice solution ;)');
subscription = source.pipe( onErrorResumeNext(planB) )
.subscribe(
value => console.log('next: ', value),
error => console.error('error: ', error),
() => console.log('complete')
);Observable.pipe(...)
import { Observable, concat } from 'rxjs';
first = Observable.create(observer => {
setTimeout(() => {
observer.next('500ms');
observer.complete();
}, 500);
});
second = Observable.create(observer => {
setTimeout(() => {
observer.next('200ms');
observer.complete();
}, 200);
});
concat( first, second ).subscribe(val =>
console.log('next:', val)
);import { Observable, merge } from 'rxjs';
first = Observable.create(observer => {
setTimeout(() => {
observer.next('500ms');
observer.complete();
}, 500);
});
second = Observable.create(observer => {
setTimeout(() => {
observer.next('200ms');
observer.complete();
}, 200);
});
merge( first, second ).subscribe(
val => console.log('next:', val)
);import { Observable, zip } from 'rxjs';
nextFunction = (label, count, interval) => (observer) => {
let i = 0;
setInterval(() => {
if (i < count) {
observer.next(`[${label}]:${i}`);
i++;
} else {
observer.complete();
}
}, interval);
}
a = Observable.create(nextFunction('A', 3, 500));
b = Observable.create(nextFunction('B', 4, 200));
zip(a, b).subscribe(val => console.log('next:', val));import { Observable, combineLatest } from 'rxjs';
nextFunction = (label, count, interval) => (observer) => {
let i = 0;
setInterval(() => {
if (i < count) {
observer.next(`[${label}]:${i}`);
i++;
} else {
observer.complete();
}
}, interval);
}
a = Observable.create(nextFunction('A', 3, 500));
b = Observable.create(nextFunction('B', 4, 200));
combineLatest(a, b).subscribe(
val => console.log('next:', val)
);import { Observable, forkJoin } from 'rxjs';
nextFunction = (label, count, interval) => (observer) => {
let i = 0;
setInterval(() => {
if (i < count) {
observer.next(`[${label}]:${i}`);
i++;
} else {
observer.complete();
}
}, interval);
}
a = Observable.create(nextFunction('A', 3, 500));
b = Observable.create(nextFunction('B', 4, 200));
forkJoin(a, b).subscribe(
val => console.log('next:', val)
);import { fromEvent } from 'rxjs';
import { switchMap, mapTo } from 'rxjs/operators';
click$ = fromEvent(document, 'click');
click$.pipe(
switchMap(() => {
console.log('call server');
return timer(3000)
.pipe( mapTo('server response') );
})
).subscribe(x => console.log(x));Create new instance of provider for every subscription
Create new instance of producer for the first subscription*
* there are few details after complete or error calls
COLD Observable
Producer 1
Producer 2
Producer N
...
Subscriber 1
Subscriber 2
Subscriber N
...
Observable
Producer 1
Subscriber 1
Subscriber 2
Subscriber N
Subject
...
Observable
Observer
import { Subject } from 'rxjs';
subj = new Subject();
subj.subscribe(
val => console.log('first next:', val),
err => console.log('first was error:', err),
() => console.log('first complete')
);
subj.next('Yes, I can');
subj.complete();
subj.subscribe(
val => console.log('second next:', val),
err => console.log('second was error:', err),
() => console.log('second complete')
);import { BehaviorSubject } from 'rxjs';
subj = new BehaviorSubject('Default value');
subj.subscribe(
val => console.log('first next:', val),
err => console.log('first was error:', err),
() => console.log('first complete')
);
subj.next( Math.floor((Math.random() * 100)) );
subj.complete();
subj.subscribe(
val => console.log('second next:', val),
err => console.log('second was error:', err),
() => console.log('second complete')
);import { ReplaySubject } from 'rxjs';
subj = new ReplaySubject();
subj.subscribe(
val => console.log('first next:', val),
err => console.log('first was error:', err),
() => console.log('first complete')
);
subj.next( Math.floor((Math.random() * 100)) );
subj.complete();
subj.subscribe(
val => console.log('second next:', val),
err => console.log('second was error:', err),
() => console.log('second complete')
);import { AsyncSubject } from 'rxjs';
subj = new AsyncSubject();
subj.subscribe(
val => console.log('first next:', val),
err => console.log('first was error:', err),
() => console.log('first complete')
);
subj.next( 1 );
subj.next( 2 );
subj.complete();
subj.subscribe(
val => console.log('second next:', val),
err => console.log('second was error:', err),
() => console.log('second complete')
);