Here is the code from Deborah Kurata’s talk RxJS Patterns in Angular | Deborah Kurata | EnterpriseNG 2020 #ngconf, so that I can quickly look it up if I need it.
Declarative Data Retrieving
products$ = this.http.get<Product[]>(this.productsUrl).pipe(
tap((data) => console.log(JSON.stringify(data))),
catchError(this.handleError)
)
products$ = this.productService.products$
Use the async
pipe in the template.
“Passing” Data
To respond to an action, use a Subject
or BehaviorSubject
.
private categorySubject = new Subject<number>();
categorySelectedAction$ = this.categorySubject.asObservable();
products$ = this.categorySelectedAction$.pipe(
switchMap((categoryId) =>
this.http.get<Product[]>(`${this.url}?cat=${catId}`)
).pipe(
tap((data) => console.log(data)),
catchError(this.handleError)
)
)
switchMap
: stops the current operation and performs the new operationconcatMap
: performs each operation one at a time, in ordermergeMap
: performs each operation concurrently
Shape on Action Pattern
products$ = this.categorySelectedAction$.pipe(
switchMap((categoryId) =>
this.http.get<Product[]>(`${this.url}?cat=${catId}`)
).pipe(
tap((data) => console.log(data)),
catchError(this.handleError)
)
)
private categorySubject = new Subject<number>();
categorySelectedAction$ = this.categorySubject.asObservable();
combineLatest
: emits a combined value when any of the Observables emits; won’t emit until all Observables have emitted at least oncemerge
: emits one value when any of the Observables emitforkJoin
: when all Observables complete, emit the last value from each Observable into an array
selectedProducts$ = combineLatest([
this.products$,
this.productSelectedAction$,
]).pipe(
map((products, selectedProductId) =>
products.find((product) => product.id === selectedProdudctId)
)
)
Retrieve Related Data Pattern
One to One
selectedProduct$ = this.productSelectedAction$.pipe(
switchMap((categoryId) => this.http.get<Product>(`${this.url}?/${id}`)).pipe(
tap((data) => console.log(data)),
catchError(this.handleError)
)
)
productSupplier$ = this.selectedProduct$.pipe(
switchMap((product) =>
this.http.get<Supplier>(`${this.url}/${product.supplierId}`)
)
)
One to Many
productSuppliers$ = this.selectedProduct$.pipe(
switchMap((product) =>
forkJoin(
product.supplierIds.map((supplierId) =>
this.http.get<Supplier>(`${this.url}/${supplierId}`)
)
)
)
)