Anton Bely
Hello world! My name is Anton Bely and I'm Product Frontend Engineer. Welcome!
npm install --save rxjs
import { Observable } from 'rxjs';
const source = new Observable(function subscribe(subscriber) {
console.log('Observable created');
let count = 0;
const timer = setInterval(() => {
subscriber.next(count);
count++;
}, 1000);
return () => {
console.log('Observable destroyed');
clearInterval(timer);
}
});
const subscription = source.subscribe(
val => console.log('next:', val),
err => console.error('error:', err),
() => console.log('completed')
);
setTimeout(() => subscription.unsubscribe(), 4500);
const source = new Observable((subscriber) => {
console.log('Observable created');
let count = 0;
const timer = setInterval(() => {
if( count < 3 ) {
subscriber.next(count++);
} else {
subscriber.error('Damn!');
}
}, 1000);
return () => {
console.log('Observable destroyed');
clearInterval(timer);
};
});
const subscription = source.subscribe(
val => console.log('next:', val),
err => console.error('error:', err),
() => console.log('completed')
);
const source = new Observable((subscriber) => {
console.log('Observable created');
let count = 0;
const timer = setInterval(() => {
if( count < 3 ) {
subscriber.next(count++);
} else {
subscriber.complete();
}
}, 1000);
return () => {
console.log('Observable destroyed');
clearInterval(timer);
}
});
const subscription = source.subscribe(
val => console.log('next:', val),
err => console.error('error:', err),
() => console.log('completed')
);
import { of } from 'rxjs';
source = of({message: 'any Object'});
subscription = source.subscribe(
val => console.log('next:', val),
err => console.error('error:', err),
() => console.log('completed')
);
import { from } from 'rxjs';
source = from([10, 20, 30]);
subscription = source.subscribe(
val => console.log('next:', val),
err => console.error('error:', err),
() => console.log('completed')
);
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';
source = throwError('Damn');
subscription = source.pipe(
catchError(err => {
console.log('catch:', err);
return of('safety result');
})
)
.subscribe(
val => console.log('next:', val),
err => console.error('error:', err),
() => console.log('completed')
);
import { Observable } from 'rxjs';
import { retry } from 'rxjs/operators';
source = new Observable(subscriber => {
console.log('Next attempt');
subscriber.error('Damn!');
});
subscription = source.pipe( retry(2) )
.subscribe(
val => console.log('next:', val),
err => console.error('handle error:', err),
() => console.log('completed')
);
import { Observable, throwError } from 'rxjs';
import { retryWhen } from 'rxjs/operators';
flag = true;
source = new Observable(subscriber => {
console.log('Fake server call');
if (flag) {
subscriber.error('Damn');
flag = false;
} else {
subscriber.next('success');
}
});
obs = new Observable(subscriber => {
console.log('let wait a second');
setTimeout(() => subscriber.next('any'), 1000);
});
subscription = source.pipe( retryWhen(err$ => obs) )
.subscribe( val => console.log('next:', val) );
import { Observable, of } from 'rxjs';
import { onErrorResumeNext } from 'rxjs/operators';
source = new Observable(subscriber => {
console.log('Attempt');
subscriber.error('Damn!');
});
planB = of('Nice solution ;)');
subscription = source.pipe( onErrorResumeNext(planB) )
.subscribe(
val => console.log('next:', val),
err => console.error('handle error:', err),
() => console.log('completed')
);
import { Observable } from 'rxjs';
promise = new Promise(resolve => {
console.log('Create Promise');
resolve('promise-result')
});
source = new Observable(subscriber => {
console.log('Create Observable');
subscriber.next('observable-result');
});
import { Observable } from 'rxjs';
promise = new Promise(resolve => {
console.log('Create Promise');
resolve('promise-result')
});
source = new Observable(subscriber => {
console.log('Create Observable');
subscriber.next('observable-result');
});
promise.then(data => console.log('handle:', data));
source.subscribe(val => console.log('handle:', val));
import { Observable } from 'rxjs';
promise = new Promise(resolve => {
console.log('Create Promise');
resolve('promise-result')
});
source = new Observable(subscriber => {
console.log('Create Observable');
subscriber.next('observable-result');
});
promise.then(data => console.log('handle:', data));
source.subscribe(val => console.log('handle:', val));
promise.then(data => console.log('handle:', data));
source.subscribe(val => console.log('handle:', val));
someArray = [10, 20, 30, 40];
result = someArray
.map(item => {
console.log('[MAP]', item);
return item + 5;
})
.filter(item => {
console.log('[FILTER]', item);
return item > 30;
})
.reduce((acc, item) => acc + item);
console.log(result);
import { from } from 'rxjs';
import { map, filter } from 'rxjs/operators';
someArray = [10, 20, 30, 40];
from(someArray).pipe(
map(item => {
console.log('[MAP]', item);
return item + 5;
}),
filter(item => {
console.log('[FILTER]', item);
return item > 30;
})
).subscribe( val => console.log('next:', val) );
import { from } from 'rxjs';
import { map, filter, reduce } from 'rxjs/operators';
someArray = [10, 20, 30, 40];
from(someArray).pipe(
map(item => {
console.log('[MAP]', item);
return item + 5;
}),
filter(item => {
console.log('[FILTER]', item);
return item > 30;
}),
reduce((acc, item) => acc + item)
).subscribe( val => console.log('next:', val) );
import { from } from 'rxjs';
import { map, filter, scan } from 'rxjs/operators';
someArray = [10, 20, 30, 40];
from(someArray).pipe(
map(item => {
console.log('[MAP]', item);
return item + 5;
}),
filter(item => {
console.log('[FILTER]', item);
return item > 30;
}),
scan((acc, item) => acc + item)
).subscribe( val => console.log('next:', val) );
import { Observable, concat } from 'rxjs';
first = new Observable(subscriber => {
setTimeout(() => {
subscriber.next('500ms');
subscriber.complete();
}, 500);
});
second = new Observable(subscriber => {
setTimeout(() => {
subscriber.next('200ms');
subscriber.complete();
}, 200);
});
concat( first, second ).subscribe(val =>
console.log('next:', val)
);
import { Observable, merge } from 'rxjs';
first = new Observable(subscriber => {
setTimeout(() => {
subscriber.next('500ms');
subscriber.complete();
}, 500);
});
second = new Observable(subscriber => {
setTimeout(() => {
subscriber.next('200ms');
subscriber.complete();
}, 200);
});
merge( first, second ).subscribe(
val => console.log('next:', val)
);
import { Observable, zip } from 'rxjs';
nextFunction = (label, count, interval) => (subscriber) => {
let i = 0;
setInterval(() => {
if (i < count) {
subscriber.next(`[${label}]:${i}`);
i++;
} else {
subscriber.complete();
}
}, interval);
}
a = new Observable( nextFunction('A', 3, 500) );
b = new Observable( nextFunction('B', 4, 200) );
zip(a, b).subscribe(val => console.log('next:', val));
import { Observable, combineLatest } from 'rxjs';
nextFunction = (label, count, interval) => (subscriber) => {
let i = 0;
setInterval(() => {
if (i < count) {
subscriber.next(`[${label}]:${i}`);
i++;
} else {
subscriber.complete();
}
}, interval);
}
a = new Observable( nextFunction('A', 3, 500) );
b = new Observable( nextFunction('B', 4, 200) );
combineLatest(a, b).subscribe(
val => console.log('next:', val)
);
import { Observable, forkJoin } from 'rxjs';
nextFunction = (label, count, interval) => (subscriber) => {
let i = 0;
setInterval(() => {
if (i < count) {
subscriber.next(`[${label}]:${i}`);
i++;
} else {
subscriber.complete();
}
}, interval);
}
a = new Observable( nextFunction('A', 3, 500) );
b = new Observable( 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
.subscribe()
.pipe()
Observer
.next()
.error()
.complete()
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 { 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')
);
*set on constructor buffer size (number)
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 { 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')
);
Observable
Producer 1
Subscriber 1
Subscriber 2
Subscriber N
Subject
...
import { defer, of } from 'rxjs';
import { multicast } from 'rxjs/operators';
random = () => Math.floor(Math.random() * 100);
cold = defer(() => of(random()));
hot = cold.pipe( multicast(new Subject()) );
hot.subscribe(x => console.log('1:', x));
hot.subscribe(x => console.log('2:', x));
hot.connect();
import { defer, of } from 'rxjs';
import { multicast } from 'rxjs/operators';
random = () => Math.floor(Math.random() * 100);
cold = defer(() => of(random()));
hot = cold.pipe( multicast(new Subject()) ).refCount();
hot.subscribe(x => console.log('1:', x));
hot.subscribe(x => console.log('2:', x));
import { defer, of } from 'rxjs';
import { multicast } from 'rxjs/operators';
random = () => Math.floor(Math.random() * 100);
cold = defer(() => of(random()));
hot = cold.pipe(
multicast(() => new Subject())
).refCount();
hot.subscribe(x => console.log('1:', x));
hot.subscribe(x => console.log('2:', x));
import { defer, of } from 'rxjs';
import { publish } from 'rxjs/operators';
random = () => Math.floor(Math.random() * 100);
cold = defer(() => of(random()));
hot = cold.pipe(publish());
hot.subscribe(x => console.log('1:', x));
hot.subscribe(x => console.log('2:', x));
hot.connect();
import { defer, of } from 'rxjs';
import { share } from 'rxjs/operators';
random = () => Math.floor(Math.random() * 100);
cold = defer(() => of(random()));
hot = cold.pipe(share());
hot.subscribe(x => console.log('1:', x));
hot.subscribe(x => console.log('2:', x));
// Service Method
public saveSomething(data) {
return this.http.post(someUrl, { data });
}
// Component Method
this.myService.saveSomething('Some info');
// Service Method
public saveSomething(data) {
return this.http.post(someUrl, { data });
}
// Component Method
this.myService.saveSomething('Some info')
.subscribe( result =>
console.log('Success! Result:', result)
);
// Service Method
public receiveData() {
return this.http.get(someUrl);
}
// Component
this.data$ = this.myService.receiveData();
this.data$.subscribe( result =>
console.log('Success! Result:', result)
);
// Component Template
<div *ngIf="(data$ | async) as data">{{ data }}</div>
... /someUrl GET 200 OK
... /someUrl GET 200 OK
By Anton Bely