takeUntil() Method for Destroying Subscriptions in Angular:

To destroy the subscription used in the component manually is a tedious task, so in order to solve this issue a solution is provided which automatically unsubscribes the subscription as soon as the component is destroyed.

Following Solution is for Angular 16 or Above:

In Angular 16, we were introduced to a new method called takeUntilDestroyed(). This method completes the Observable when the calling context (component, directive, service, etc) is destroyed.

import { Component } from "@angular/core"; 
import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; 
@Component({ 
selector: "my-component", 
templateUrl: "./my-component.html", 
styleUrls: ["./my-component.scss"] 
}) 

export class MyComponent { 
constructor(private http: HttpClient) { 
this.http.get('/api').pipe(takeUntilDestroyed()).subscribe(); 
} 
}

NOTE: If you are trying to do the same outside of the constructor you may see this error takeUntilDestroyed() can only be used within an injection context such as a constructor To fix this update to the following

import { Component, DestroyRef, OnInit, inject } from "@angular/core"; 
import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; 
@Component({ 
selector: "my-component", 
templateUrl: "./my-component.html", 
styleUrls: ["./my-component.scss"] 
}) 

export class MyComponent implements OnInit { 
destroyedRef = inject(DestroyRef); 
ngOnInit(): void { 
this.http.get('/api').pipe(takeUntilDestroyed(this.destroyedRef)).subscribe(); 
} 
}

Following Solution is for Angular 15 or Below:

In this version, we only had the takeUntil() method, so we had to rely on a subject variable in order to store the reference for the subscription.

When Using RxJS 6.x:

Note the use of the pipe() method.

class myComponent { 
private destroyed$: ReplaySubject = new ReplaySubject(1); 

constructor( private serviceA: ServiceA, private serviceB: ServiceB, private serviceC: ServiceC) {} 
ngOnInit() { 
this.serviceA .pipe(takeUntil(this.destroyed$)) .subscribe(...); 
this.serviceB .pipe(takeUntil(this.destroyed$)) .subscribe(...); 
this.serviceC .pipe(takeUntil(this.destroyed$)) .subscribe(...); 
} 

ngOnDestroy() { 
this.destroyed$.next(true); this.destroyed$.complete(); 
}
 }

This is only valid for RxJS 5.x and older:

class myComponentOld { 
private destroyed$: ReplaySubject = new ReplaySubject(1); 

constructor(private serviceA: ServiceA) {} 
ngOnInit() {
 this.serviceA .takeUntil(this.destroyed$) .subscribe(...); 
} 
ngOnDestroy() { 
this.destroyed$.next(true); this.destroyed$.complete();
 } 
}

Support On Demand!

Angular