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);
});
}
}