RxJS library and Observables explained

The Observable pattern provides the new way used in angular to deliver values between a publisher and its subscriber, and angular takes advantage of the RxJS library to exploit it.

Observable

Multiple Push collection. Register all the values produced. To access to this value, it's necessary to subscribe to it. That's why it exposes a method subscribe to see these values.

Observer

Handler for receiving observable notifications. It defines a next method that handles each delivered value. Can define an error method and a completemethod.

Subscribe

The subscribe method is necessary to access to an observable values. To subscribe to an observable, an easy way is to create a subscription, subscribe, use the values, and remember to unsubscribe when the component is destroyed.

private subscription: Subscription = Subscription.EMPTY;
ngOnInit() {
  this._subscription = this.observable$.subscribe((res) =>{
    this.doSomething(res);
    this.cd.markForCheck();
  } );
}
ngOnDestroy() {
  this._subscription.unsubscribe();
}

In this case, if the DetectionStrategy is onPush, the component inside the subscribe method might have to ask to update for changes, with the this.cd.markForCheck() instruction.

In the template, the pipe async subscribe and unsubscribe automatically, passing to the children the observed values. This is a good article about the differences between subscribe and async pipe: https://medium.com/angular-in-depth/angular-question-rxjs-subscribe-vs-async-pipe-in-component-templates-c956c8c0c794

Operators

Operators transform the values emitted by an observable. The operators can be of different types, and usually are chained inside a pipe operator. There are a lot of them, below you can find some useful use cases.

shareReplay

When an observable has multiple subscriptions, use shareReplay to evaluate the observable just once and share it's value. For example when there are more then one | async in the template for the same observable.

Simulate if-then-else

Often there is no need to use RxJS operators for the if-then-else behavior, because this construct can be used inside a switchMapor concatMap block.

this.filteredOptions$ = this._inputValue$.pipe(
  debounceTime(200),
  distinctUntilChanged(),
  switchMap((term) => {
    if (term && term.length > 2) {
      return this._customerService.searchCustomersGet("", term || "");
    } else {
      return of({ items: [] });
    }
  })
);

if this is not possible, use iif, that subscribes to first or second observable based on a condition.

Subject

Subjects is both a observable (you can subscribe to it) and an observer (it has next, error and complete methods). Subject is the minimal version, no state, all that gets pushed with next is lost if no subscribers. They are used in a multicasting scenario.

BehaviorSubject

Behaviour subject has state, the last emitted value or the one used in the constructor. Any new subscriber, will receive that stored value when it subscribes and the all the future emitted values.

ReplaySubject

ReplaySubject is a Subject that stores the number of previous emitted values indicated in the constructor. When it receives a new subscriber, it emits the last n values (if they exist) and the all the new values.

Add subscriptions

The add method is very useful to put together subscriptions, maybe related. In this way the unsubscribe() method unsubscribes from all of them. Be careful to not reassign the subscription, or it will be replaced without unsubscribe it. To use it, first create the subscription:

this._mySubscription = new Subscription();

And then add to that sink using the add method:

this._mySubscription.add((this.form.get(
  'controlName',
) as FormControl).valueChanges.subscribe(($val) =>
  consoleLog($val)
));

Remember to write the unsubscribe method in the ngOnDestroy:

this._mySubscriptionKeyname.unsubscribe();