Skip to main content

Unsubscribe observables with RxJS takeUntil

Step 11 — Unsubscribing from HttpClient Observables with RxJS takeUntil()

In this step of our Angular 13 tutorial, we'll learn about why we need and how to unsubscribe from Observables in our code using the takeUntil() operator.

First of all, do you need to unsubscribe from the Observables returned by the HttpClient methods?

Generally, you need to manually unsubscribe from any subscribed RxJS Observables in your Angular components to avoid memory leaks but in the case of HttpClient, this is automatically handled by Angular by unsubscribing when the HTTP response is received. However, there are some cases when you need to manually unsubscribe for example to cancel pending requests when users are about to leave the component.

We can simply call the unsubscribe() method from the Subscription object returned by the subscribe() method in the ngOnDestroy() life-cycle method of the component to unsubscribe from the Observable.

There is also a better way to unsubscribe from or complete Observables by using the takeUntil() operator.

The takeUntil() operator emits the values emitted by the source Observable until a notifier Observable emits a value.

Let's see how to use this operator to complete Observables when the component is destroyed.

Check out How to cancel/unsubscribe all pending HTTP requests angular 4+.

Open the src/app/home/home.component.ts file and update it as follows:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataService } from '../data.service';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {

products = [];
destroy$: Subject<boolean> = new Subject<boolean>();

constructor(private dataService: DataService) { }

ngOnInit() {

this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((data: any[])=>{
console.log(data);
this.products = data;
})
}
ngOnDestroy() {
this.destroy$.next(true);
// Unsubscribe from the subject
this.destroy$.unsubscribe();
}

}

We first imported the OnDestroy interface, Subject and the takeUntil() operator. Next, we implemented the OnDestroy interface and added the ngOnDestroy() lifecycle hook to the component.

Next, we created an instance of Subject which can emit boolean values (the type of the value doesn't really matter in this example) that will be used as the notifier of the takeUntil() operator.

Next, in the ngOnInit() lifecycle hook, we called the sendGetRequest() of our data service and called the pipe() method of the returned Observable to pipe the takeUnitl() operator and finaly subscribed to the combined Observable. In the body of the subscribe() method, we added the logic to put the fetched data of the HTTP response in the products array.

The takeUntil() operator allows a notified Observable to emit values until a value is emitted from a notifier Observable.

When Angular destroys a component it calls the ngOnDestroy() lifecycle method which, in our case, calls the next() method to emit a value so RxJS completes all subscribed Observables.

That's it. In this step, we have added the logic to cancel any pending HTTP request by unsubscribing from the returned Observable in case the user descides to navigate away from the component before the HTTP response is received.

Also read how to Unsubscribe from the RxJS subjects when the Angular component is destroyed

In the next step of our Angular 13 tutorial, we'll see how to use URL query parameters with the get() method of HttpClient.