Angular: should I unsubscribe from switchMap

Viewed 2335

I've got the following component:

@Component({...})
export class AppComponent implements OnInit, OnDestroy {

  destroy$ = new Subject();
  update$ = new Subject();

  result: Result;

  constructor(service: Service) {
  }

  ngOnInit() {
    update$.pipe(
      takeUntil(this.destroy$),
      switchMap(() => this.service.get())
    ).subscribe(result => this.result = result);

    this.refresh();
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }

  refresh() {
    this.update$.next();
  }

}

Is this approach correct? Or should I call takeUntil(this.destroy$) after switchMap?

update$.pipe(
  switchMap(() => this.service.get()),
  takeUntil(this.destroy$)
).subscribe(result => this.result = result);

Or should I call it twice?

update$.pipe(
  takeUntil(this.destroy$),
  switchMap(() => this.service.get()),
  takeUntil(this.destroy$)
).subscribe(result => this.result = result);
2 Answers

The cleanest way is to call takeUntil after switchMap.

update$.pipe(
  switchMap(() => this.service.get()),
  takeUntil(this.destroy$)
).subscribe(result => this.result = result);

This will prevent any emissions to the subscription. If you add takeUntil before, the switchMap subscription will emit values until the observable returned by the project function completes, which may be never (depending on your service code).

It is not necessary to call takeUntil both before and after switchMap, because the switchMap unsubscribes from the source observable (everything before switchMap) when itself it is unsubscribed from.

Typically you would want takeUntil should be the last operator. In your case this is the correct approach:

update$.pipe(
  switchMap(() => this.service.get()),
  takeUntil(this.destroy$)
).subscribe(result => this.result = result);
Related