SlideShare uma empresa Scribd logo
1 de 88
Baixar para ler offline
OPERATORS YOU ACTUALLY CARE
ABOUT EXPLAINED FOR REAL WORLD
USE CASES
OPERATORS IN RXJS
TRACY LEE
@ladyleet
Lead, This Dot Labs, JS consulting (Angular, React, Vue, Node, Polymer)
RxJS Core Team
Google Developer Expert, Angular
Microsoft MVP
Community Rel, Node.js @ OpenJS Foundation
Women Techmakers, GDG Silicon Valley & Triangle
Modern Web Podcast
@ladyleet
THE ANATOMY OF AN OPERATOR
“operators” in Observables
import { of as observableOf } from 'rxjs';
import { map, filter } from 'rxjs/operators';
const src = observableOf(1, 2, 3, 4, 5, 6, 7);
src.pipe(
filter(x => x % 2 === 0),
map(x => x + x),
).subscribe(x => console.log(x)); // 4...8...12...
A simple map operator implementation
import { Observable } from 'rxjs';
export function map(fn) {
return (source) => new Observable(observer => {
return source.subscribe({
next(value) { observer.next(fn(value)); },
error(err) { observer.error(err); },
complete() { observer.complete(); },
});
});
}
Takes an observable & returns a new one
import { Observable } from 'rxjs';
export function map(fn) {
return (source) => new Observable(observer => {
return source.subscribe({
next(value) { observer.next(fn(value)); },
error(err) { observer.error(err); },
complete() { observer.complete(); },
});
});
}
Subscribes to the source
import { Observable } from 'rxjs';
export function map(fn) {
return (source) => new Observable(observer => {
return source.subscribe({
next(value) { observer.next(fn(value)); },
error(err) { observer.error(err); },
complete() { observer.complete(); },
});
});
}
Passes along the transformed value
import { Observable } from 'rxjs';
export function map(fn) {
return (source) => new Observable(observer => {
return source.subscribe({
next(value) { observer.next(fn(value)); },
error(err) { observer.error(err); },
complete() { observer.complete(); },
});
});
}
And sending along the other signals
import { Observable } from 'rxjs';
export function map(fn) {
return (source) => new Observable(observer => {
return source.subscribe({
next(value) { observer.next(fn(value)); },
error(err) { observer.error(err); },
complete() { observer.complete(); },
});
});
}
@ladyleet
● Flattening Operators
● Error Handling
● Completion Operators
● Subjects & Multicasting
There are 60+ operators in RxJS
map
filter
scan
THE EASIEST
OPERATORS
Deep Dive
Podcast
EXPLANATION -
Applies a reducer function over the source Observable, and
returns each intermediate result, with an optional seed value.
PRIMARY USES -
Managing state in a stream. No ngrx! You can use scan to create a
redux pattern.
scan
https://rxjs.dev/api/operators/scan
Deep Dive
Podcast
COMMON MISTAKES -
Emitting the same reference multiple times, which can cause
problems.
What you should do instead is treat your accumulated value as
immutable.
scan
https://rxjs.dev/api/operators/scan
FLATTENING
OPERATORS
FLATTENING
OPERATORS
switchMap
concatMap
mergeMap
exhaustMap
FLATTENING
OPERATORS
switchMap
concatMap
mergeMap
exhaustMap
Deep Dive
Podcast
EXPLANATION -
● Maps a value to a new observable,
● subscribes to that observable,
● unsubscribes from the previous observable it was subscribed
to.
(switchMap only subscribes to one observable at a time)
switchMap
https://rxjs.dev/api/operators/switchMap
switchMap
i$:
input$:
output$:
switchMap(fn)
fn: (v) => interval(1000).pipe(take(2))
a
i1$:
i2$:
b
A B
A
B
fn
fn
U
B
B
Deep Dive
Podcast
PRIMARY USES -
Commonly used for HTTP GET.
Great for autocompletes
Toggling between two streams
Great for animation!
switchMap
https://rxjs.dev/api/operators/switchMap
Deep Dive
Podcast
COMMON MISTAKES -
If you’re doing an HTTP POST or DELETE and a value is coming back in
the response.
If you’re relying on response from POST or DELETE in order to update
the UI, you’re only going to get response from 2nd request, and not 1st.
In these situations, use concatMap instead.
switchMap
https://rxjs.dev/api/operators/switchMap
FLATTENING
OPERATORS
switchMap
concatMap
mergeMap
exhaustMap
Deep Dive
Podcast
EXPLANATION -
Most common operator for HTTP requests.
Ensures everything happens in the order it arrived.
Takes a value from the source, maps it into a new observable, and
only runs one observable at a time until it completes. Then moves
on to the next value in the buffer.
concatMap
https://rxjs.dev/api/operators/concatMap
concatMap
i$:
input$:
output$:
concatMap(fn)
fn: (v) => interval(1000).pipe(take(2))
a
i1$:
i2$:
b
A A B B
A A
B B
fn
fn
Deep Dive
Podcast
COMMON MISTAKES -
Every single time you use concatMap, you have to make sure the observable
ends.
Never use concatMap for toggling or endless streams.
If the stream never completes, every subsequent concatMap is just going to
build up the buffer, and the other observables it’s buffering will never run.
concatMap
https://rxjs.dev/api/operators/concatMap
FLATTENING
OPERATORS
switchMap
concatMap
mergeMap
exhaustMap
Deep Dive
Podcast
EXPLANATION -
Takes every single value, maps it into an observable, and
subscribes to it.
Then, it outputs whatever is coming from those inner observables
as a single stream of values.
mergeMap
https://rxjs.dev/api/operators/mergeMap
Deep Dive
Podcast
PRIMARY USES -
Sending requests to get as many responses as fast as possible when you don’t
care about the response order.
Errors from requests: mergeMap is more useful than switchMap if you want to
know what errors come back from requests and be able to handle them.
(With switchMap, the subscription would be cancelled before the error comes
back)
mergeMap
https://rxjs.dev/api/operators/mergeMap
i$:
input$:
output$:
mergeMap(fn)
fn: (v) => interval(1000).pipe(take(2))
a
i1$:
i2$:
b
A AB B
A A
B B
fn
fn
A B
A
B
mergeMap
Deep Dive
Podcast
COMMON MISTAKES -
Using mergeMap to map to HTTP requests.
You don’t know how long a server will take to respond, and if one
request is slow and another is fast, it will end up out of order.
(If you don’t care about order, you can use it)
mergeMap
https://rxjs.dev/api/operators/mergeMap
FLATTENING
OPERATORS
switchMap
concatMap
mergeMap
exhaustMap
Deep Dive
Podcast
EXPLANATION - Conceptually, exhaustMap is the opposite of
switchMap.
Every time a value arrives, if you’re not already subscribed to a
previously mapped-to observable, exhaustMap will map it into an
observable and subscribe to that.
It will wait for the inner observable to complete or “exhaust” itself
before it allows any more new source values to be mapped into a new
inner observable.
exhaustMap
https://rxjs.dev/api/operators/exhaustMap
Deep Dive
Podcast
EXAMPLE USES -
Great for preventing double submissions.
Making sure touch drag features work properly.
exhaustMap
https://rxjs.dev/api/operators/exhaustMap
// Run a finite timer for each click, only if there is no
currently active timer
import { fromEvent, interval } from 'rxjs';
import { exhaustMap, take } from 'rxjs/operators';
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(
exhaustMap(ev => interval(1000).pipe(take(5)))
);
result.subscribe(x => console.log(x));
exhaustMap example
ERROR HANDLING
ERROR HANDLING
ERROR
HANDLING
catchError
retry
retryWhen
ERROR
HANDLING
catchError
retry
retryWhen
Deep Dive
Podcast
EXPLANATION -
Prevents errors from traveling down the entire chain.
Catches errors on the Observable to be handled by returning a
new Observable or throwing an error.
When it gets an error, it maps that error into a new Observable
and replaces the original source observable with the new one.
catchError
https://rxjs.dev/api/operators/catchError
output$:
catchError
input$:
catchError(fn)
3 fn (e:any) => EMPTYn:
fn
Deep Dive
Podcast
PRIMARY USES -
Handling errors from observables by mapping them to new
observable.
Preventing HTTP errors from killing the entire observable chain.
catchError
https://rxjs.dev/api/operators/catchError
// A stream of "load button" clicks
const loadData = fromEvent(button, 'click');
// When we click "load", trigger an http get
loadData.pipe(
concatMap(() => ajax.get('/this/will/404').pipe(
catchError(err => {
// side effect, to log something happened
console.log('An error occurred loading your
stuff!');
// Return a different observable
return of({ message: 'We noticed an error' });
})
))
).subscribe(x => console.log(x));
catchError example
ERROR
HANDLING
catchError
retry
retryWhen
Deep Dive
Podcast
EXPLANATION -
If your observable errors, it will resubscribe to that observable a
specified number of times.
retry
https://rxjs.dev/api/operators/retry
Deep Dive
Podcast
PRIMARY USES -
Great in the case of an HTTP request or websocket stream where
there is network flakiness.
When it gets an error signal, it resubscribes to the original source.
retry
https://rxjs.dev/api/operators/retry
output$:
retry
input$:
retry(n)
1 uR Unsubscribes and recycles observablen:
uR
// RxJS v6+ - Retry 2 times on error
import { interval, of, throwError } from
'rxjs';
import { mergeMap, retry } from
'rxjs/operators';
const source = interval(1000);
const example = source.pipe(
mergeMap(val => {
//throw error for demonstration
if (val > 5) {
return throwError('Error!');
}
return of(val);
}),
retry example
//retry 2 times on error
retry(2)
);
const subscribe = example.subscribe({
next: val => console.log(val),
error: val => console.log(`${val}:
Retried 2 times then quit!`)
});
Deep Dive
Podcast
COMMON MISTAKES -
Using retry without an argument.
Using retry on hot observables.
(If you’re using a Subject or stateful observable, it’s not going to
reset the state of that observable, just resubscribe to it)
retry
https://rxjs.dev/api/operators/retry
catchError
retry
retryWhen
ERROR
HANDLING
Deep Dive
Podcast
EXPLANATION -
Gives you more control than retry.
Gives you an observable of errors that you can map into an
observable of notifications of when you want to retry.
retryWhen
https://rxjs.dev/api/operators/retryWhen
Deep Dive
Podcast
PRIMARY USES -
Using retry with a delay i.e incremental step back on network
failure
(if you send a network request and it fails - wait 2 seconds, try
again, if it fails, wait 4 and try, then 8 and try, etc.)
retryWhen
https://rxjs.dev/api/operators/retryWhen
output$:
retryWhen
input$:
retryWhen(fn)
1 fn (errors$) => errors$.pipe(switchMap(e => e.message === ‘X’ ? throwError(e) : of(1)))n:
fn
fn
COMPLETION
OPERATORS
COMPLETION
OPERATORS
take
takeUntil
takeWhile
first
COMPLETION
OPERATORS
take
takeUntil
takeWhile
first
Deep Dive
Podcast
EXPLANATION -
Takes the first specified number of values.
PRIMARY USES -
If you want to take the first n values from the source observable.
take
https://rxjs.dev/api/operators/take
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
const intervalCount = interval(1000);
const takeFive = intervalCount.pipe(take(5));
takeFive.subscribe(x => console.log(x));
take example
COMPLETION
OPERATORS
take
takeUntil
takeWhile
first
Deep Dive
Podcast
EXPLANATION -
Using a notifier observable to tell a source observable to
complete.
PRIMARY USES -
Declarative subscription management
takeUntil
https://rxjs.dev/api/operators/takeUntil
output$:
takeUntil
input$:
takeUntil(t$)
fromEvent(document.body, ‘click’)t$:
t$:
U
Deep Dive
Podcast
COMMON MISTAKES -
Providing the source observable with a notifier that never emits or
completes.
https://rxjs.dev/api/operators/takeUntil
takeUntil
COMPLETION
OPERATORS
take
takeUntil
takeWhile
first
Deep Dive
Podcast
EXPLANATION -
Emits values emitted by the source observable so long as each
value satisfies the given predicate…
and then completes as soon as this predicate is not satisfied.
takeWhile
https://rxjs.dev/api/operators/takeWhile
import { fromEvent } from 'rxjs';
import { takeWhile } from 'rxjs/operators';
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(takeWhile(ev => ev.clientX >
200));
result.subscribe(x => console.log(x));
takeWhile example
import { fromEvent } from 'rxjs';
import { takeWhile } from 'rxjs/operators';
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(takeWhile(ev => ev.clientX >
200, true));
result.subscribe(x => console.log(x));
takeWhile’s new feature (inclusive)
Deep Dive
Podcast
PRIMARY USES -
Limit for mouse movements
Progress bars
COMMON MISTAKES - Not realizing that takeWhile has to wait for a
value to arrive before it completes and using it when you actually
wanted the observable to complete after an external event.
In this scenario you should have used takeUntil.
takeWhile
https://rxjs.dev/api/operators/takeWhile
COMPLETION
OPERATORS
take
takeUntil
takeWhile
first
Deep Dive
Podcast
EXPLANATION - Emits only the first value (or the first value that meets
some condition) emitted by the source Observable, or a default value.
If no default value is provided, it will error if it does not get a first value.
PRIMARY USES -
Used when you want to get the very next value from a websocket or
from an update interval.
first
https://rxjs.dev/api/operators/first
import { fromEvent } from 'rxjs';
import { first } from 'rxjs/operators';
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(first(ev => ev.target.tagName
=== 'DIV'));
result.subscribe(x => console.log(x));
first example
Deep Dive
Podcast
COMMON MISTAKES -
Not realizing that first will error if it never finds a first value, and does
not have a default value.
(In this case, you probably wanted a filter and a take)
https://rxjs.dev/api/operators/first
first
SUBJECTS AND
MULTICASTING
SUBJECTS AND
MULTICASTING
Subject
BehaviorSubject
ReplaySubject
share
shareReplay
SUBJECTS AND
MULTICASTING
Subject
BehaviorSubject
ReplaySubject
share
shareReplay
Deep Dive
Podcast
EXPLANATION -
A Subject is an observable that is also an observer.
PRIMARY USES -
Multicasting is the main use case for Subject.
Getting an observable out of user events ie button clicks.
Subject
https://rxjs.dev/api/index/class/Subject
Deep Dive
Podcast
COMMON MISTAKES - You should not just use Subject because
you don’t understand how to create an observable.
With Subjects, you do not get guaranteed teardown and memory
management that you would get with Observable.
After a Subject has errored or completed, it’s no longer usable.
https://rxjs.dev/api/index/class/Subject
Subject
SUBJECTS AND
MULTICASTING
Subject
BehaviorSubject
ReplaySubject
share
shareReplay
Deep Dive
Podcast
EXPLANATION -
A variant of Subject that requires an initial value and emits its
current value whenever it is subscribed to.
PRIMARY USES -
When you don’t want a user or system to wait to get the next
value.
BehaviorSubject
https://rxjs.dev/api/index/class/BehaviorSubject
SUBJECTS AND
MULTICASTING
Subject
BehaviorSubject
ReplaySubject
share
shareReplay
Deep Dive
Podcast
EXPLANATION - Returns a new Observable that multicasts
(shares) the original Observable.
As long as there is at least one Subscriber this Observable will be
subscribed and emitting data.
When all subscribers have unsubscribed it will unsubscribe from
the source Observable.
PRIMARY USES - Multicasting
share
https://rxjs.dev/api/operators/map
Deep Dive
Podcast
COMMON MISTAKES - Using publish or multicast when you should be using
share or shareReplay.
The reason you should use share / shareReplay is because under the hood
publish and multicast only have one instance of subject, so you can’t retry it if
there is an error.
Share automatically recycles the subject under the hood to allow you to
resubscribe to the subject.
When it errors or completes it will recycle and create a brand new instance so
it’s not completely dead. https://rxjs.dev/api/operators/share
share
Subject
BehaviorSubject
ReplaySubject
share
shareReplay
SUBJECTS AND
MULTICASTING
Deep Dive
Podcast
EXPLANATION - Same as share, but keeps the underlying ReplaySubject so the
next subscriber gets all the successful results and successful completion.
shareReplay does ref counting under the hood, but keeps a ref count of 1 to
make sure it can run to completion and to ensure the next subscriber gets the
last cached value.
PRIMARY USES - Retrieving expensive data via HTTP and you don’t want to get
it twice
shareReplay
https://rxjs.dev/api/operators/shareReplay
Deep Dive
Podcast
COMMON MISTAKES -
There is a configuration object - after the last subscriber unsubscribes,
you can actually recycle, but that is not the default behavior and it
confuses a lot of people.
You should always have at least 1 argument passed into ShareReplay.
ShareReplay without an argument will cache every single value that it
had nexted into it and replay those to new subscribers.
shareReplay
https://rxjs.dev/api/operators/shareReplay
@ladyleet
● Flattening Operators
● Error Handling
● Completion Operators
● Subjects & Multicasting
There are 60+ operators in RxJS
RxJS OPERATOR VIDEO SERIES
https://bit.ly/2IstZwM
@ladyleet
COME CONTRIBUTE!
THANK YOU
@benlesh
Angular Core Team,
RxJS Author
@michael_hladky
Google Developer
Expert, Angular
OUR
LINKS www.thisdot.co
This Dot Media
/thisdotmedia
news.thisdot.co
hi@thisdot.co
THANK YOU!

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Server side rendering review
Server side rendering reviewServer side rendering review
Server side rendering review
 
Angular Observables & RxJS Introduction
Angular Observables & RxJS IntroductionAngular Observables & RxJS Introduction
Angular Observables & RxJS Introduction
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
React Js Simplified
React Js SimplifiedReact Js Simplified
React Js Simplified
 
React
React React
React
 
Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular
 
React Context API
React Context APIReact Context API
React Context API
 
Getting started with typescript
Getting started with typescriptGetting started with typescript
Getting started with typescript
 
React js use contexts and useContext hook
React js use contexts and useContext hookReact js use contexts and useContext hook
React js use contexts and useContext hook
 
Solid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJSSolid NodeJS with TypeScript, Jest & NestJS
Solid NodeJS with TypeScript, Jest & NestJS
 
Initiation à Express js
Initiation à Express jsInitiation à Express js
Initiation à Express js
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React Alicante
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0
 
Ngrx slides
Ngrx slidesNgrx slides
Ngrx slides
 
Introduction to ReactJS
Introduction to ReactJSIntroduction to ReactJS
Introduction to ReactJS
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
React js
React jsReact js
React js
 
Introduction to react_js
Introduction to react_jsIntroduction to react_js
Introduction to react_js
 

Semelhante a RxJS Operators - Real World Use Cases - AngularMix

Semelhante a RxJS Operators - Real World Use Cases - AngularMix (20)

RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
The Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on Android
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
State management in a GraphQL era
State management in a GraphQL eraState management in a GraphQL era
State management in a GraphQL era
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Reactive programming in Angular 2
Reactive programming in Angular 2Reactive programming in Angular 2
Reactive programming in Angular 2
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
 
RxJava 2 Reactive extensions for the JVM
RxJava 2  Reactive extensions for the JVMRxJava 2  Reactive extensions for the JVM
RxJava 2 Reactive extensions for the JVM
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
Side effects-con-redux
Side effects-con-reduxSide effects-con-redux
Side effects-con-redux
 
Project Reactor Now and Tomorrow
Project Reactor Now and TomorrowProject Reactor Now and Tomorrow
Project Reactor Now and Tomorrow
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrow
 
The Reactive Landscape
The Reactive LandscapeThe Reactive Landscape
The Reactive Landscape
 
RxJava@Android
RxJava@AndroidRxJava@Android
RxJava@Android
 
RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015RxJS In-Depth - AngularConnect 2015
RxJS In-Depth - AngularConnect 2015
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Cycle.js - A functional reactive UI framework
Cycle.js - A functional reactive UI frameworkCycle.js - A functional reactive UI framework
Cycle.js - A functional reactive UI framework
 
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
Cycle.js - Functional reactive UI framework (Nikos Kalogridis)
 

Mais de Tracy Lee

Mais de Tracy Lee (20)

Contributing to Open Source - Angular World Tour
Contributing to Open Source - Angular World TourContributing to Open Source - Angular World Tour
Contributing to Open Source - Angular World Tour
 
ChicagoJS's JSCAMP 2019 Keynote - Inclusive Architecture - Building Sustainab...
ChicagoJS's JSCAMP 2019 Keynote - Inclusive Architecture - Building Sustainab...ChicagoJS's JSCAMP 2019 Keynote - Inclusive Architecture - Building Sustainab...
ChicagoJS's JSCAMP 2019 Keynote - Inclusive Architecture - Building Sustainab...
 
Angular Girls Kansas City - The Power of Open Source and Social Media
Angular Girls Kansas City - The Power of Open Source and Social MediaAngular Girls Kansas City - The Power of Open Source and Social Media
Angular Girls Kansas City - The Power of Open Source and Social Media
 
Diversity & Inclusion Conference Talk - Refactr
Diversity & Inclusion Conference Talk - RefactrDiversity & Inclusion Conference Talk - Refactr
Diversity & Inclusion Conference Talk - Refactr
 
Inclusive Architecture - Introducing the PAMstack - [Refactr.tech]
Inclusive Architecture - Introducing the PAMstack - [Refactr.tech] Inclusive Architecture - Introducing the PAMstack - [Refactr.tech]
Inclusive Architecture - Introducing the PAMstack - [Refactr.tech]
 
Diversity, Inclusive Mindsets, and Architecture
Diversity, Inclusive Mindsets, and ArchitectureDiversity, Inclusive Mindsets, and Architecture
Diversity, Inclusive Mindsets, and Architecture
 
Diversity & Inclusion Keynote at Open Source 101
Diversity & Inclusion Keynote at Open Source 101Diversity & Inclusion Keynote at Open Source 101
Diversity & Inclusion Keynote at Open Source 101
 
Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018Reactive programming with RxJS - ByteConf 2018
Reactive programming with RxJS - ByteConf 2018
 
A Practical Approach to React Native at All Things Open Conference
A Practical Approach to React Native at All Things Open ConferenceA Practical Approach to React Native at All Things Open Conference
A Practical Approach to React Native at All Things Open Conference
 
The Power of RxJS in Nativescript + Angular
The Power of RxJS in Nativescript + AngularThe Power of RxJS in Nativescript + Angular
The Power of RxJS in Nativescript + Angular
 
React Native - Getting Started
React Native - Getting StartedReact Native - Getting Started
React Native - Getting Started
 
RxJS - The Basics & The Future
RxJS - The Basics & The FutureRxJS - The Basics & The Future
RxJS - The Basics & The Future
 
RxJS: A Beginner & Expert's Perspective - ng-conf 2017
RxJS: A Beginner & Expert's Perspective - ng-conf 2017RxJS: A Beginner & Expert's Perspective - ng-conf 2017
RxJS: A Beginner & Expert's Perspective - ng-conf 2017
 
An Introduction Into Using Angular’s Material Design
An Introduction Into Using Angular’s Material DesignAn Introduction Into Using Angular’s Material Design
An Introduction Into Using Angular’s Material Design
 
The Tale of the 3 CLIs - jDays2017
The Tale of the 3 CLIs - jDays2017The Tale of the 3 CLIs - jDays2017
The Tale of the 3 CLIs - jDays2017
 
Angular Material (2) - NgVikingsConf
Angular Material (2) - NgVikingsConfAngular Material (2) - NgVikingsConf
Angular Material (2) - NgVikingsConf
 
Using Angular-CLI to Deploy an Angular 2 App Using Firebase in 30 Minutes
Using Angular-CLI to Deploy an Angular 2 App Using Firebase in 30 MinutesUsing Angular-CLI to Deploy an Angular 2 App Using Firebase in 30 Minutes
Using Angular-CLI to Deploy an Angular 2 App Using Firebase in 30 Minutes
 
A Tale of 3 CLIs - Angular 2, Ember, and React
A Tale of 3 CLIs - Angular 2, Ember, and ReactA Tale of 3 CLIs - Angular 2, Ember, and React
A Tale of 3 CLIs - Angular 2, Ember, and React
 
Learning the New Tech Lingua Franca: Social Media
Learning the New Tech Lingua Franca: Social MediaLearning the New Tech Lingua Franca: Social Media
Learning the New Tech Lingua Franca: Social Media
 
From 0 to Developer - Silicon Valley Code Camp
From 0 to Developer - Silicon Valley Code CampFrom 0 to Developer - Silicon Valley Code Camp
From 0 to Developer - Silicon Valley Code Camp
 

Último

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

RxJS Operators - Real World Use Cases - AngularMix

  • 1. OPERATORS YOU ACTUALLY CARE ABOUT EXPLAINED FOR REAL WORLD USE CASES OPERATORS IN RXJS
  • 2. TRACY LEE @ladyleet Lead, This Dot Labs, JS consulting (Angular, React, Vue, Node, Polymer) RxJS Core Team Google Developer Expert, Angular Microsoft MVP Community Rel, Node.js @ OpenJS Foundation Women Techmakers, GDG Silicon Valley & Triangle Modern Web Podcast
  • 4. “operators” in Observables import { of as observableOf } from 'rxjs'; import { map, filter } from 'rxjs/operators'; const src = observableOf(1, 2, 3, 4, 5, 6, 7); src.pipe( filter(x => x % 2 === 0), map(x => x + x), ).subscribe(x => console.log(x)); // 4...8...12...
  • 5. A simple map operator implementation import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  • 6. Takes an observable & returns a new one import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  • 7. Subscribes to the source import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  • 8. Passes along the transformed value import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  • 9. And sending along the other signals import { Observable } from 'rxjs'; export function map(fn) { return (source) => new Observable(observer => { return source.subscribe({ next(value) { observer.next(fn(value)); }, error(err) { observer.error(err); }, complete() { observer.complete(); }, }); }); }
  • 10. @ladyleet ● Flattening Operators ● Error Handling ● Completion Operators ● Subjects & Multicasting There are 60+ operators in RxJS
  • 12. Deep Dive Podcast EXPLANATION - Applies a reducer function over the source Observable, and returns each intermediate result, with an optional seed value. PRIMARY USES - Managing state in a stream. No ngrx! You can use scan to create a redux pattern. scan https://rxjs.dev/api/operators/scan
  • 13. Deep Dive Podcast COMMON MISTAKES - Emitting the same reference multiple times, which can cause problems. What you should do instead is treat your accumulated value as immutable. scan https://rxjs.dev/api/operators/scan
  • 17. Deep Dive Podcast EXPLANATION - ● Maps a value to a new observable, ● subscribes to that observable, ● unsubscribes from the previous observable it was subscribed to. (switchMap only subscribes to one observable at a time) switchMap https://rxjs.dev/api/operators/switchMap
  • 18. switchMap i$: input$: output$: switchMap(fn) fn: (v) => interval(1000).pipe(take(2)) a i1$: i2$: b A B A B fn fn U B B
  • 19. Deep Dive Podcast PRIMARY USES - Commonly used for HTTP GET. Great for autocompletes Toggling between two streams Great for animation! switchMap https://rxjs.dev/api/operators/switchMap
  • 20. Deep Dive Podcast COMMON MISTAKES - If you’re doing an HTTP POST or DELETE and a value is coming back in the response. If you’re relying on response from POST or DELETE in order to update the UI, you’re only going to get response from 2nd request, and not 1st. In these situations, use concatMap instead. switchMap https://rxjs.dev/api/operators/switchMap
  • 22. Deep Dive Podcast EXPLANATION - Most common operator for HTTP requests. Ensures everything happens in the order it arrived. Takes a value from the source, maps it into a new observable, and only runs one observable at a time until it completes. Then moves on to the next value in the buffer. concatMap https://rxjs.dev/api/operators/concatMap
  • 23. concatMap i$: input$: output$: concatMap(fn) fn: (v) => interval(1000).pipe(take(2)) a i1$: i2$: b A A B B A A B B fn fn
  • 24. Deep Dive Podcast COMMON MISTAKES - Every single time you use concatMap, you have to make sure the observable ends. Never use concatMap for toggling or endless streams. If the stream never completes, every subsequent concatMap is just going to build up the buffer, and the other observables it’s buffering will never run. concatMap https://rxjs.dev/api/operators/concatMap
  • 26. Deep Dive Podcast EXPLANATION - Takes every single value, maps it into an observable, and subscribes to it. Then, it outputs whatever is coming from those inner observables as a single stream of values. mergeMap https://rxjs.dev/api/operators/mergeMap
  • 27. Deep Dive Podcast PRIMARY USES - Sending requests to get as many responses as fast as possible when you don’t care about the response order. Errors from requests: mergeMap is more useful than switchMap if you want to know what errors come back from requests and be able to handle them. (With switchMap, the subscription would be cancelled before the error comes back) mergeMap https://rxjs.dev/api/operators/mergeMap
  • 28. i$: input$: output$: mergeMap(fn) fn: (v) => interval(1000).pipe(take(2)) a i1$: i2$: b A AB B A A B B fn fn A B A B mergeMap
  • 29. Deep Dive Podcast COMMON MISTAKES - Using mergeMap to map to HTTP requests. You don’t know how long a server will take to respond, and if one request is slow and another is fast, it will end up out of order. (If you don’t care about order, you can use it) mergeMap https://rxjs.dev/api/operators/mergeMap
  • 31. Deep Dive Podcast EXPLANATION - Conceptually, exhaustMap is the opposite of switchMap. Every time a value arrives, if you’re not already subscribed to a previously mapped-to observable, exhaustMap will map it into an observable and subscribe to that. It will wait for the inner observable to complete or “exhaust” itself before it allows any more new source values to be mapped into a new inner observable. exhaustMap https://rxjs.dev/api/operators/exhaustMap
  • 32. Deep Dive Podcast EXAMPLE USES - Great for preventing double submissions. Making sure touch drag features work properly. exhaustMap https://rxjs.dev/api/operators/exhaustMap
  • 33. // Run a finite timer for each click, only if there is no currently active timer import { fromEvent, interval } from 'rxjs'; import { exhaustMap, take } from 'rxjs/operators'; const clicks = fromEvent(document, 'click'); const result = clicks.pipe( exhaustMap(ev => interval(1000).pipe(take(5))) ); result.subscribe(x => console.log(x)); exhaustMap example
  • 38. Deep Dive Podcast EXPLANATION - Prevents errors from traveling down the entire chain. Catches errors on the Observable to be handled by returning a new Observable or throwing an error. When it gets an error, it maps that error into a new Observable and replaces the original source observable with the new one. catchError https://rxjs.dev/api/operators/catchError
  • 40. Deep Dive Podcast PRIMARY USES - Handling errors from observables by mapping them to new observable. Preventing HTTP errors from killing the entire observable chain. catchError https://rxjs.dev/api/operators/catchError
  • 41. // A stream of "load button" clicks const loadData = fromEvent(button, 'click'); // When we click "load", trigger an http get loadData.pipe( concatMap(() => ajax.get('/this/will/404').pipe( catchError(err => { // side effect, to log something happened console.log('An error occurred loading your stuff!'); // Return a different observable return of({ message: 'We noticed an error' }); }) )) ).subscribe(x => console.log(x)); catchError example
  • 43. Deep Dive Podcast EXPLANATION - If your observable errors, it will resubscribe to that observable a specified number of times. retry https://rxjs.dev/api/operators/retry
  • 44. Deep Dive Podcast PRIMARY USES - Great in the case of an HTTP request or websocket stream where there is network flakiness. When it gets an error signal, it resubscribes to the original source. retry https://rxjs.dev/api/operators/retry
  • 46. // RxJS v6+ - Retry 2 times on error import { interval, of, throwError } from 'rxjs'; import { mergeMap, retry } from 'rxjs/operators'; const source = interval(1000); const example = source.pipe( mergeMap(val => { //throw error for demonstration if (val > 5) { return throwError('Error!'); } return of(val); }), retry example //retry 2 times on error retry(2) ); const subscribe = example.subscribe({ next: val => console.log(val), error: val => console.log(`${val}: Retried 2 times then quit!`) });
  • 47. Deep Dive Podcast COMMON MISTAKES - Using retry without an argument. Using retry on hot observables. (If you’re using a Subject or stateful observable, it’s not going to reset the state of that observable, just resubscribe to it) retry https://rxjs.dev/api/operators/retry
  • 49. Deep Dive Podcast EXPLANATION - Gives you more control than retry. Gives you an observable of errors that you can map into an observable of notifications of when you want to retry. retryWhen https://rxjs.dev/api/operators/retryWhen
  • 50. Deep Dive Podcast PRIMARY USES - Using retry with a delay i.e incremental step back on network failure (if you send a network request and it fails - wait 2 seconds, try again, if it fails, wait 4 and try, then 8 and try, etc.) retryWhen https://rxjs.dev/api/operators/retryWhen
  • 51. output$: retryWhen input$: retryWhen(fn) 1 fn (errors$) => errors$.pipe(switchMap(e => e.message === ‘X’ ? throwError(e) : of(1)))n: fn fn
  • 55. Deep Dive Podcast EXPLANATION - Takes the first specified number of values. PRIMARY USES - If you want to take the first n values from the source observable. take https://rxjs.dev/api/operators/take
  • 56. import { interval } from 'rxjs'; import { take } from 'rxjs/operators'; const intervalCount = interval(1000); const takeFive = intervalCount.pipe(take(5)); takeFive.subscribe(x => console.log(x)); take example
  • 58. Deep Dive Podcast EXPLANATION - Using a notifier observable to tell a source observable to complete. PRIMARY USES - Declarative subscription management takeUntil https://rxjs.dev/api/operators/takeUntil
  • 60. Deep Dive Podcast COMMON MISTAKES - Providing the source observable with a notifier that never emits or completes. https://rxjs.dev/api/operators/takeUntil takeUntil
  • 62. Deep Dive Podcast EXPLANATION - Emits values emitted by the source observable so long as each value satisfies the given predicate… and then completes as soon as this predicate is not satisfied. takeWhile https://rxjs.dev/api/operators/takeWhile
  • 63. import { fromEvent } from 'rxjs'; import { takeWhile } from 'rxjs/operators'; const clicks = fromEvent(document, 'click'); const result = clicks.pipe(takeWhile(ev => ev.clientX > 200)); result.subscribe(x => console.log(x)); takeWhile example
  • 64. import { fromEvent } from 'rxjs'; import { takeWhile } from 'rxjs/operators'; const clicks = fromEvent(document, 'click'); const result = clicks.pipe(takeWhile(ev => ev.clientX > 200, true)); result.subscribe(x => console.log(x)); takeWhile’s new feature (inclusive)
  • 65. Deep Dive Podcast PRIMARY USES - Limit for mouse movements Progress bars COMMON MISTAKES - Not realizing that takeWhile has to wait for a value to arrive before it completes and using it when you actually wanted the observable to complete after an external event. In this scenario you should have used takeUntil. takeWhile https://rxjs.dev/api/operators/takeWhile
  • 67. Deep Dive Podcast EXPLANATION - Emits only the first value (or the first value that meets some condition) emitted by the source Observable, or a default value. If no default value is provided, it will error if it does not get a first value. PRIMARY USES - Used when you want to get the very next value from a websocket or from an update interval. first https://rxjs.dev/api/operators/first
  • 68. import { fromEvent } from 'rxjs'; import { first } from 'rxjs/operators'; const clicks = fromEvent(document, 'click'); const result = clicks.pipe(first(ev => ev.target.tagName === 'DIV')); result.subscribe(x => console.log(x)); first example
  • 69. Deep Dive Podcast COMMON MISTAKES - Not realizing that first will error if it never finds a first value, and does not have a default value. (In this case, you probably wanted a filter and a take) https://rxjs.dev/api/operators/first first
  • 73. Deep Dive Podcast EXPLANATION - A Subject is an observable that is also an observer. PRIMARY USES - Multicasting is the main use case for Subject. Getting an observable out of user events ie button clicks. Subject https://rxjs.dev/api/index/class/Subject
  • 74. Deep Dive Podcast COMMON MISTAKES - You should not just use Subject because you don’t understand how to create an observable. With Subjects, you do not get guaranteed teardown and memory management that you would get with Observable. After a Subject has errored or completed, it’s no longer usable. https://rxjs.dev/api/index/class/Subject Subject
  • 76. Deep Dive Podcast EXPLANATION - A variant of Subject that requires an initial value and emits its current value whenever it is subscribed to. PRIMARY USES - When you don’t want a user or system to wait to get the next value. BehaviorSubject https://rxjs.dev/api/index/class/BehaviorSubject
  • 78. Deep Dive Podcast EXPLANATION - Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will unsubscribe from the source Observable. PRIMARY USES - Multicasting share https://rxjs.dev/api/operators/map
  • 79. Deep Dive Podcast COMMON MISTAKES - Using publish or multicast when you should be using share or shareReplay. The reason you should use share / shareReplay is because under the hood publish and multicast only have one instance of subject, so you can’t retry it if there is an error. Share automatically recycles the subject under the hood to allow you to resubscribe to the subject. When it errors or completes it will recycle and create a brand new instance so it’s not completely dead. https://rxjs.dev/api/operators/share share
  • 81. Deep Dive Podcast EXPLANATION - Same as share, but keeps the underlying ReplaySubject so the next subscriber gets all the successful results and successful completion. shareReplay does ref counting under the hood, but keeps a ref count of 1 to make sure it can run to completion and to ensure the next subscriber gets the last cached value. PRIMARY USES - Retrieving expensive data via HTTP and you don’t want to get it twice shareReplay https://rxjs.dev/api/operators/shareReplay
  • 82. Deep Dive Podcast COMMON MISTAKES - There is a configuration object - after the last subscriber unsubscribes, you can actually recycle, but that is not the default behavior and it confuses a lot of people. You should always have at least 1 argument passed into ShareReplay. ShareReplay without an argument will cache every single value that it had nexted into it and replay those to new subscribers. shareReplay https://rxjs.dev/api/operators/shareReplay
  • 83. @ladyleet ● Flattening Operators ● Error Handling ● Completion Operators ● Subjects & Multicasting There are 60+ operators in RxJS
  • 84. RxJS OPERATOR VIDEO SERIES https://bit.ly/2IstZwM
  • 86. THANK YOU @benlesh Angular Core Team, RxJS Author @michael_hladky Google Developer Expert, Angular
  • 87. OUR LINKS www.thisdot.co This Dot Media /thisdotmedia news.thisdot.co