Angular course · Module 7: RxJS
Subscription Management
In this lesson4
Memory leaks from unfinished subscriptions are a serious problem - like a ninja who forgot to return from a mission!
takeUntilDestroyed (Angular 16+) - Recommended
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DestroyRef, inject } from '@angular/core';
@Component({...})
export class ModernComponent {
private destroyRef = inject(DestroyRef);
constructor() {
// Automatically completes when the component is destroyed
this.dataService.getData().pipe(
takeUntilDestroyed()
).subscribe(data => {
this.processData(data);
});
// Can also be used outside the constructor
this.loadData();
}
loadData(): void {
this.http.get('/api/data').pipe(
takeUntilDestroyed(this.destroyRef)
).subscribe();
}
}Traditional Approach with Subject
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({...})
export class TraditionalComponent implements OnDestroy {
private destroy$ = new Subject<void>();
ngOnInit(): void {
this.dataService.getData().pipe(
takeUntil(this.destroy$)
).subscribe(data => {
this.processData(data);
});
// Multiple subscriptions
this.otherService.getOther().pipe(
takeUntil(this.destroy$)
).subscribe();
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}AsyncPipe - Automatic Management
@Component({
template: `
@if (samuraiList$ | async; as samuraiList) {
@for (s of samuraiList; track s.id) {
<div>{{ s.name }}</div>
}
} @else {
<p>Loading...</p>
}
`
})
export class SamuraiListComponent {
// AsyncPipe automatically subscribes and unsubscribes!
samuraiList$ = this.http.get<Samurai[]>('/api/samurai');
}Subscription Collection
import { Subscription } from 'rxjs';
@Component({...})
export class CollectionComponent implements OnDestroy {
private subscriptions = new Subscription();
ngOnInit(): void {
// Add subscriptions to the collection
this.subscriptions.add(
this.service1.data$.subscribe()
);
this.subscriptions.add(
this.service2.data$.subscribe()
);
}
ngOnDestroy(): void {
// One line cancels all
this.subscriptions.unsubscribe();
}
}Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What is the recommended way to manage subscriptions in Angular 16+?
2. What does AsyncPipe do automatically?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Horizontal ordering
Arrange the import of the takeUntilDestroyed operator from the interop package:
- Code editor
Complete the code so that the interval() subscription ends by itself when the component is destroyed.
- Vertical ordering
Arrange the steps of the traditional subscription cleanup pattern with Subject in the order they appear in a component:
- Click in order
Arrange the AsyncPipe expression with an alias in a template: samurai$ | async; as samurai