Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I be completing my subject after nexted in angular ngOnDestroy

Tags:

angular

rxjs

I usually use takeUntil(this.destroySub) when I need to manually subscribe to a stream in my components. Does it matter (for the subject (garbage collection or whatnot) - since nexting is enough to complete the stream) whether I complete the subject or not in the ngOnDestroy?

@Component({...})
class MyComponent {
  private destroySub = new Subject<void>();

  constructor() { 
    of('some stream').pipe(
      takeUntil(this.destroySub)
    ).subscribe()
  }

  ngOnDestroy():void {
    this.destroySub.next();
    this.destroySub.complete();
  }
}
like image 487
XT_Nova Avatar asked Oct 19 '25 05:10

XT_Nova


1 Answers

Short Answer.

takeUntil(this.destroySub) is how you're completing all the other observables in your component, but this doesn't complete this.destroySub itself.

Yes, subjects don't have a finite lifetime, so you should complete them when you don't need them anymore.

The Longer Answer

Just like any other object, the GC will still collect a Subject once there are no more pointers to it. The issue with this way of thinking is that it's oh so very easy to accidentally leak a reference to this subject. Because it's an asynchronous library, references can be on both the current stack and the also the event loop.

Your working inside a framework that may try to optimize your components, so there's no guarantee the reference to your component is dropped inside Angular after ngOnDestroy is called. You're also passing references to the RxJS library for every time you use takeUntil(this.destroySub). RxJS proxies and manages emissions for you in many cases, so you may to surprised by a relatively mundane line of code causing a memory leak.

Completing an observable cleans up all the internal instrumentation that RxJS keeps for any given observable and leaves your conscious clear in that regard.

So yes, even though (if you're careful and well informed) the GC may clean up an incomplete observable, I wouldn't count on it. If your observable isn't finite, then make it finite somehow. this.destroySub.complete(); does that work for you.

like image 124
Mrk Sef Avatar answered Oct 21 '25 22:10

Mrk Sef



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!