How to unsubscribe RxJs Observable in Angular

Each time you call subscribe method on RxJs Observable, you should (most of the time) also call unsubscribe. See how you can do it in Angular components.

October 2, 2022 angularangular-15

Unsubscribe on ngOnDestroy hook

Advantages:

Disadvantages:

@Component({})
export class MyComponent implements OnInit, OnDestroy {
  private sub1!: Subscription;
  private sub2!: Subscription;

  ngOnInit(): void {
    this.sub1 = interval(1000).subscribe();
    this.sub2 = interval(1000).subscribe();
  }

  ngOnDestroy(): void {
    this.sub1.unsubscribe();
    this.sub2.unsubscribe();
  }
}

Unsubscribe on ngOnDestroy hook with subscriptions container

Advantages:

Disadvantages:

@Component({})
export class MyComponent implements OnInit, OnDestroy {
  private subs = new Subscription();

  ngOnInit(): void {
    const sub1 = interval(1000).subscribe();
    const sub2 = interval(1000).subscribe();

    this.subs.add(sub1);
    this.subs.add(sub2);
  }

  ngOnDestroy(): void {
    this.subs.unsubscribe();
  }
}

Unsubscribe with async pipe

Advantages:

Disadvantages:

@Component({
  template: `
    <ng-container *ngIf="interval1$ | async"></ng-container>
    <ng-container *ngIf="interval2$ | async"></ng-container>
  `,
})
export class MyComponent {
  interval1$ = interval(1000);
  interval2$ = interval(1000);
}

Complete stream with takeUnitl operator

Advantages:

Disadvantages:

@Component({})
export class MyComponent implements OnInit, OnDestroy {
  private destroy$ = new Subject<void>();

  ngOnInit(): void {
    interval(1000).pipe(takeUntil(this.destroy$)).subscribe();
    interval(1000).pipe(takeUntil(this.destroy$)).subscribe();
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }
}

Unsubscribe/Complete with destroyable local service

Thanks to destroyable local service you can move unsubscribe logic outside the component.

Advantages:

Disadvantages:

@Injectable()
export class Unsubscriber extends Subject<void> implements OnDestroy {
  private subs = new Subscription();

  set add(sub: Subscription) {
    this.subs.add(sub);
  }

  ngOnDestroy(): void {
    this.next();
    this.complete();
    this.subs.unsubscribe();
  }
}
@Component({
  providers: [Unsubscriber],
})
export class MyComponent implements OnInit {
  constructor(private unsubscriber: Unsubscriber) {}

  ngOnInit(): void {
    // with takeUntil pattern
    interval(1000).pipe(takeUntil(this.unsubscriber)).subscribe();

    // with unsubscribe pattern
    this.unsubscriber.add = interval(1000).subscribe();
  }
}

Do you like the content?

Your support helps me continue my work. Please consider making a donation.

Donations are accepted through PayPal or Stripe. You do not need a account to donate. All major credit cards are accepted.

Leave a comment