Observable Anxiety

Ein passender Titel für den Vortrag auf der NG-CONF 2018 von Ward Bell & Sander Ellis zum Thema „Angular APIs with RxJS“:

.pipe your Observables!

Angular APIs using RxJS: HttpClient, AsyncPipe, Forms, Router:

  • .get() with .subscribe() in your service, .pipe() the Observable and map() it there to the object you want to consume in your components, then use the service in your components
  • .post() with .subscribe(), including error-handling
  • or get the data with using async in your template and error handling (catchError()) in the component
  • with Angular reactive forms APIs valueChanges-Observable, .pipe() with tap() for error message, and three functions to reduce http-requests: debounceTime(), disctinctUntilChanged() and switchMap() for discarding an inflight-search, .pipe()‚d again to sandbox the errors inside the switchMap() so that examining the Observable does not complete, e.g. for auto-completion (use reactive style instead of Angular template-driven forms)
  • error isolation (explicit example) for sandboxing errors in an isolation level with the help of another .pipe() to map() and catchError() inside the .pipe() to switchMap(). RxJS rule: if an error occurs, the upstream is dead.
  • ActivatedRoute used with Observable paramMap.pipe(), Router events and url address path change while navigating on the same component with changing routerParams, map() and then switchMap(), again to cancel previous queries. Including watching the routing for debugging (altenrnative .subscribe()-style!)
  • Recommended way if subscribing to an Observable: .unsubscribe() from the source, a Subject, with Observable.onDestroy.next() in life cycle event hook ngOnDestroy() with the aid of Observable.pipe() to takeUntil() emitting the Subject in the Observable.pipe() to complete the Observable which prevents memory leaks. .unsubscribe() when in doubt with takeUntil(notifier) pattern. It never hurts to .unsubscribe()!
  •  .subscribe() takes: 1.) the happy (or: the next channel), 2.) the sad (or: the error channel) and 3.) alert things when the Observable completes (which means the Observable terminates and let go of any subscribers)
  • async autosubscribes when the Component is destroyed, but emits no „completed“: savely use AsyncPipe in the components template!
  • combine multistreams: bring multiple streams from Observers and Subjects together with combineLatest() .pipe()‘d to map() for mapping them into an immutable array of immutable objects
  • role your own Observables which have .next(), .error() and .complete(), from properties („rolling http of local storage“) in the component
  • create a new result array when any source emits an Observable array with .pipe()‚ing the Observable to scan(), which accumulates all incoming Observables into an array starting empty with startWith( [] ). combineLatest() takes the latest value of every Observable it gets
  • sort values in an additional map()
  • (not in movie) filter() the .pipe()‚d Observable to filter out unwanted values

Observable Decision Graph:

Source fork (Angular 7 / Node 10 commit):