How to unsubscribe from Observable in Angular
When working with Observables in Angular, it's important to unsubscribe from them to prevent memory leaks.
In this article, I'll show you 4 different ways to unsubscribe from an Observable in Angular.
Using unsubscribe() method in ngOnDestroy hook#
You can manually unsubscribe from an Observable in the ngOnDestroy() lifecycle hook:
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent implements OnDestroy {
subscription: Subscription;
ngOnInit() {
this.subscription = this.myService.getData().subscribe(data => {
console.log(data);
});
}
ngOnDestroy() {
// Unsubscribe to prevent memory leaks
this.subscription.unsubscribe();
}
}
Using async Pipe in templates (Recommended)#
The async pipe automatically handles subscription and unsubscription, so you don't need to unsubscribe manually. This is especially useful when displaying data in templates.
<div *ngIf="data$ | async as data">
{{ data }}
</div>
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent {
data$ = this.myService.getData();
}
Using takeUntil with Subject (Recommended)#
This method is useful when you have multiple Observables and want to unsubscribe from all of them in one place. You use a Subject to emit a value when the component is destroyed.
import { Component, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit() {
this.myService.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(data => {
console.log(data);
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
Using take or first Operator#
If you only need one value from the Observable, you can use the take(1) or first() operator to automatically complete the subscription after one emission.
import { Component } from '@angular/core';
import { take } from 'rxjs/operators';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent implements OnInit {
ngOnInit() {
this.myService.getData()
.pipe(take(1))
.subscribe(data => {
console.log(data);
});
}
}