We use cookies to enhance your experience on the site
CodeWorlds

Subscription Management

Memory leaks from unfinished subscriptions are a serious problem - like a ninja who forgot to return from a mission!

takeUntilDestroyed (Angular 16+) - Recommended

1import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2import { DestroyRef, inject } from '@angular/core';
3
4@Component({...})
5export class ModernComponent {
6  private destroyRef = inject(DestroyRef);
7
8  constructor() {
9    // Automatically completes when the component is destroyed
10    this.dataService.getData().pipe(
11      takeUntilDestroyed()
12    ).subscribe(data => {
13      this.processData(data);
14    });
15
16    // Can also be used outside the constructor
17    this.loadData();
18  }
19
20  loadData(): void {
21    this.http.get('/api/data').pipe(
22      takeUntilDestroyed(this.destroyRef)
23    ).subscribe();
24  }
25}

Traditional Approach with Subject

1import { Subject } from 'rxjs';
2import { takeUntil } from 'rxjs/operators';
3
4@Component({...})
5export class TraditionalComponent implements OnDestroy {
6  private destroy$ = new Subject<void>();
7
8  ngOnInit(): void {
9    this.dataService.getData().pipe(
10      takeUntil(this.destroy$)
11    ).subscribe(data => {
12      this.processData(data);
13    });
14
15    // Multiple subscriptions
16    this.otherService.getOther().pipe(
17      takeUntil(this.destroy$)
18    ).subscribe();
19  }
20
21  ngOnDestroy(): void {
22    this.destroy$.next();
23    this.destroy$.complete();
24  }
25}

AsyncPipe - Automatic Management

1@Component({
2  template: \`
3    @if (samuraiList$ | async; as samuraiList) {
4      @for (s of samuraiList; track s.id) {
5        <div>{{ s.name }}</div>
6      }
7    } @else {
8      <p>Loading...</p>
9    }
10  \`
11})
12export class SamuraiListComponent {
13  // AsyncPipe automatically subscribes and unsubscribes!
14  samuraiList$ = this.http.get<Samurai[]>('/api/samurai');
15}

Subscription Collection

1import { Subscription } from 'rxjs';
2
3@Component({...})
4export class CollectionComponent implements OnDestroy {
5  private subscriptions = new Subscription();
6
7  ngOnInit(): void {
8    // Add subscriptions to the collection
9    this.subscriptions.add(
10      this.service1.data$.subscribe()
11    );
12
13    this.subscriptions.add(
14      this.service2.data$.subscribe()
15    );
16  }
17
18  ngOnDestroy(): void {
19    // One line cancels all
20    this.subscriptions.unsubscribe();
21  }
22}
Go to CodeWorlds