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.

RxJS Patterns in Angular | Deborah Kurata | EnterpriseNG 2020 #ngconf

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 operation
  • concatMap: performs each operation one at a time, in order
  • mergeMap: 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 once
  • merge: emits one value when any of the Observables emit
  • forkJoin: 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)
  )
)

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}`)
      )
    )
  )
)