Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Observable destroy with takeUntil: What happens when .next() is missing in ngOnDestroy

In an Angular 7 Component, I use the RxJS takeUntil() to properly unsubscribe on observable subscriptions.

  • What happens when the this.destroy$.next() is missing in the method ngOnDestroy (see sample below)? Will it still unsubscribe properly?
  • What happens when the this.destroy$.complete() is missing in the method ngOnDestroy (see sample below)? Will it still unsubscribe properly?
  • Is there any way to enforce that pattern with takeUntil() to unsubscribe is properly used (e.g. tslint rule, npm package)?

@Component({
    selector: 'app-flights',
    templateUrl: './flights.component.html'
})
export class FlightsComponent implements OnDestroy, OnInit {
    private readonly destroy$ = new Subject();

    public flights: FlightModel[];

    constructor(private readonly flightService: FlightService) { }

    ngOnInit() {
        this.flightService.getAll()
            .pipe(takeUntil(this.destroy$))
            .subscribe(flights => this.flights = flights);
    }

    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
}
like image 619
Horace P. Greeley Avatar asked Oct 16 '22 10:10

Horace P. Greeley


2 Answers

  1. takeUntil takes next as emission. If only complete() called it won't unsubscribe

try this out:

const a=new Subject();
interval(1000).pipe(takeUntil(a)).subscribe(console.log);
timer(3000).subscribe(_=>a.complete())
  1. this.destroy$ is still in the memory and won't get garbage collected
  2. Not that i am aware of

Please also take a look here to avoid memory leak when using takeUntil.

https://medium.com/angular-in-depth/rxjs-avoiding-takeuntil-leaks-fb5182d047ef

Personally I prefer explicit unsubscribe upon destroy.

like image 186
Fan Cheung Avatar answered Oct 20 '22 11:10

Fan Cheung


Here's a simpler approach:

private readonly destroy$ = new Subject<boolean>();

...

ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
}
like image 39
Paul Story Avatar answered Oct 20 '22 11:10

Paul Story