In Angular, is this a valid way to check whether an observable subscription is open before attempting to close it?

Viewed 14162

In Angular, is this a valid way of checking whether an observable subscription is open before attempting to close it? It seems to produce the correct behavior. That is, it only closes subscriptions that are open. What I am wondering is whether there is some more "correct" way of doing it in Angular.

import { Component, OnUpdate, OnDestroy } from '@angular/core';
import { AngularFirestore } from 'angularfire2/firestore';
import { VoteService } from '../../services/vote.service';

export class Foo implements OnUpdate, OnDestroy {

  private voteSubscription;

  constructor(private afs: AngularFirestore,public voteService: VoteService) {}

  ngOnUpdate() {

    /* Lots of complicated things happen here which result in voteSubscription
       being opened and closed based on external conditions including but not
       limited to auth state. Bottom line is that sometimes the subscription
       is active and sometimes it's not. */

       if ( CONSTANTLY_CHANGING_INPUT_CONDITIONS ) {
          this.voteSubscription = this.voteService.getUserVotes().subscribe();
        } else {
          if (this.voteSubscription) {
            this.voteSubscription.unsubscribe();
          }
        }

  }

  ngOnDestroy() {

    /* Avoid producing a console error if we try to close a subscription that is
       already closed. */
    if (this.voteSubscription) {
      this.voteSubscription.unsubscribe();
    }

  }

}
3 Answers

The Subscription object also has a closed property that one can use to check if the stream was already unsubscribed (completed or had an error).

So if you want you can use it also in the if statement:

if (this.voteSubscription && !this.voteSubscription.closed) 

However this is not needed, RxJs does this internally for us. Inside the unsubscribe method you'll find something like:

if (this.closed) {
      return;
    }

So one can safely call unsubscribe without having to worry the the stream might have been closed already.

You can use this too:

import {Subscriber} from 'rxjs';

this.voteSubscription instanceof Subscriber // returns true if is a subscriber

The following must be enough if voteSubscription is really Subscription. Otherwise there is no need to unsubscribe

ngOnDestroy() {
    this.voteSubscription?.unsubscribe();
}
Related