WebDev Guild

RxJS

Wojciech Trawiński

Bydgoszcz, 2019

Slides

https://slides.com/wojtrawi/webdev-guild-rxjs

 

About me

WebDeveloper working at Huuuge Games.

Passionate of Angular, RxJS, TypeScript and functional programming.

About me

Owner of JavaScript everyday blog

Writer for Angular In Depth and Angular Love blogs

WebDeveloper working at Huuuge Games.

Passionate of Angular, RxJS, TypeScript and functional programming.

Reactive programming

... a declarative programming paradigm

concerned with data streams and the propagation of change.

Reactive programming

... a declarative programming paradigm

concerned with data streams and the propagation of change.

Object Oriented Programming

Reactive Programming

everything is a class

everything is a stream

RxJS

In a nutshell:

  • Reactive Extensions Library for JavaScript,
  • make it easier to compose asynchronous or callback-based code,
  • Observable is the most basic building block.

RxJS

In a nutshell:

  • Reactive Extensions Library for JavaScript,
  • make it easier to compose asynchronous or callback-based code,
  • Observable is the most basic building block.

Observable

Observer

subscribe

notifications

Observer

Types of observable notifications:

  • next,
  • error,
  • complete.

Observer

Types of observable notifications:

  • next,
  • error,
  • complete.

An observer may be interested in different kinds of notifications

and corresponding callbacks may be provided in the following ways:

Observer

Types of observable notifications:

  • next,
  • error,
  • complete.

An observer may be interested in different kinds of notifications

and corresponding callbacks may be provided in the following ways:

as object

interval(1000).subscribe({
  next: console.log,
  error: console.error,
  complete: () => console.log('completed')
});

Observer

Types of observable notifications:

  • next,
  • error,
  • complete.

An observer may be interested in different kinds of notifications

and corresponding callbacks may be provided in the following ways:

as object

as successive arguments

interval(1000).subscribe(
  console.log,
  console.error,
  () => console.log('completed')
);
interval(1000).subscribe({
  next: console.log,
  error: console.error,
  complete: () => console.log('completed')
});

Observable

A representation of any set of values

over any amount of time

Observable

A representation of any set of values

over any amount of time

RxJS provides a large number of creational operators:

  • of, from, pairs (streaming existing data),
  • interval, timer, range (generating data),
  • from, fromEvent, ajax (hooking into existing api),
  • merge, combineLatest, zip (combining existing streams).

Streaming existing data

const numbers = [1, 2, 3];

const source$ = from(numbers);

source$.subscribe(console.log);

//console output: 1, 2, 3

Streaming existing data

Generating data

const numbers = [1, 2, 3];

const source$ = from(numbers);

source$.subscribe(console.log);

//console output: 1, 2, 3
const source$ = interval(5000);

source$.subscribe(console.log);

//console output (every 5s): 0, 1, 2, 3 ...

Streaming existing data

Generating data

Hooking into existing api

const numbers = [1, 2, 3];

const source$ = from(numbers);

source$.subscribe(console.log);

//console output: 1, 2, 3
const source$ = ajax('https://jsonplaceholder.typicode.com/users/1');

source$.subscribe(({ response }) => console.log(response));

//console output: object for user with id = 1
const source$ = interval(5000);

source$.subscribe(console.log);

//console output (every 5s): 0, 1, 2, 3 ...

Streaming existing data

Generating data

Hooking into existing api

Combining existing streams

const numbers = [1, 2, 3];

const source$ = from(numbers);

source$.subscribe(console.log);

//console output: 1, 2, 3
const user1$ = ajax('https://jsonplaceholder.typicode.com/users/1');
const user2$ = ajax('https://jsonplaceholder.typicode.com/users/2');

const users$ = merge(user1$, user2$);

users$.subscribe(({ response }) => console.log(response));

//console output: objects for users with 1 and 2 id
const source$ = interval(5000);

source$.subscribe(console.log);

//console output (every 5s): 0, 1, 2, 3 ...
const source$ = ajax('https://jsonplaceholder.typicode.com/users/1');

source$.subscribe(({ response }) => console.log(response));

//console output: object for user with id = 1

Creating observable from scratch

import { Observable } from 'rxjs';

const myAwesomeStream$ = new Observable(observer => {
  let counter = 0;

  const interval = setInterval(() => {
    observer.next(counter++);
  }, 1000);

  return () => clearInterval(interval);
});

const mySubscription =  myAwesomeStream$.subscribe(console.log);

setTimeout(() => {
  mySubscription.unsubscribe();
}, 2500);

//console output: 0, 1

The callback passed to the Observable constructor will be called upon subscription with an observer passed to the subscribe method

Hot & Cold Observables

Hot & Cold Observables

Hot

Observable closes over notifications producer

…like watching a movie at the cinema:

  • single source for all observers,
  • if you’re late, you’ll miss the beginning.

Hot & Cold Observables

Hot

Cold

Observable closes over notifications producer

…like watching a movie at the cinema:

  • single source for all observers,
  • if you’re late, you’ll miss the beginning.

Notifications producer created at subscription

…like watching a movie on Netflix:

  • each observer gets own source,
  • no way to be late.

Subjects

… [multicasting] is the primary use case for Subjects in RxJS

Subjects

… [multicasting] is the primary use case for Subjects in RxJS

Subject is both Observable and Observer

import { Subject, interval } from 'rxjs';

const source$ = interval(1000);
const mySubject = new Subject();

source$.subscribe(mySubject);

mySubject.subscribe(val => console.log(`#1 ${val}`));

setTimeout(() => {
  mySubject.subscribe(val => console.log(`#2 ${val}`));
}, 5000);

cold

Subject

O1

O2

Subjects

… [multicasting] is the primary use case for Subjects in RxJS

Subject is both Observable and Observer

Types of Subjects:

•Subject,

•BehaviorSubject,

•ReplaySubject,

•AsyncSubject.

cold

Subject

O1

O2

import { Subject, interval } from 'rxjs';

const source$ = interval(1000);
const mySubject = new Subject();

source$.subscribe(mySubject);

mySubject.subscribe(val => console.log(`#1 ${val}`));

setTimeout(() => {
  mySubject.subscribe(val => console.log(`#2 ${val}`));
}, 5000);

Operators

A function which accepts a stream and returns a new observable

Operators

A function which accepts a stream and returns a new observable

corresponding to array methods

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

const numbers = [1, 2, 3, 4, 5];

const source$ = from(numbers);

const result$ = source$.pipe(
  map(number => number * 10),
  filter(number => number > 30)
);

result$.subscribe(console.log);

console output: 40, 50

Operators

A function which accepts a stream and returns a new observable

corresponding to array methods

encapsulating common logic

import { interval } from 'rxjs';
import { throttleTime } from 'rxjs/operators';

const fastSource$ = interval(10);

const result$ = fastSource$.pipe(
  throttleTime(2000)
);

result$.subscribe(console.log);
import { from } from 'rxjs';
import { map, filter } from 'rxjs/operators';

const numbers = [1, 2, 3, 4, 5];

const source$ = from(numbers);

const result$ = source$.pipe(
  map(number => number * 10),
  filter(number => number > 30)
);

result$.subscribe(console.log);

console output: 40, 50
import { from } from 'rxjs';
import { map, filter } from 'rxjs/operators';

const numbers = [1, 2, 3, 4, 5];

const source$ = from(numbers);

const result$ = source$.pipe(
  map(number => number * 10),
  filter(number => number > 30)
);

result$.subscribe(console.log);

console output: 40, 50

Let's code!

 

Exercises

https://stackblitz.com/edit/hg-workshop-11-2019-task-1

https://stackblitz.com/edit/hg-workshop-11-2019-task-2

https://stackblitz.com/edit/hg-workshop-11-2019-task-3

https://stackblitz.com/edit/hg-workshop-11-2019-task-4

 

Let's code!

 

Solutions

https://stackblitz.com/edit/hg-workshop-11-2019-task-1-solution

https://stackblitz.com/edit/hg-workshop-11-2019-task-2-solution

https://stackblitz.com/edit/hg-workshop-11-2019-task-3-solution

https://stackblitz.com/edit/hg-workshop-11-2019-task-4-solution

 

Thanks

for your attention!

wojtrawi@gmail.com

WebDev Guild RxJS

By wojtrawi

WebDev Guild RxJS

  • 307