DEV Community

Cover image for This Angular helper function has saved me from memory leaks for 4 years
Geoffroy Empain
Geoffroy Empain

Posted on

This Angular helper function has saved me from memory leaks for 4 years

I have been working with Angular for more than 4 years now. From Angular 2 to Angular 10, this helper function has followed me everywhere:

export function unsubscribe(subscription: Subscription | Subscription[]) {
  const subscriptions = Array.isArray(subscription) ? subscription : [subscription];
  subscriptions.forEach(s => {
    if (s && !s.closed) {
      s.unsubscribe();
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

and here's how to use it:

@Component({
  selector: 'my-component',
  template: `
    <div>
      {{counter}}
    </div>
  `
})
export class MyComponent implements OnInit, OnDestroy {

  private subscriptions = [];

  counter = 0;

  ngOnInit() {
    this.subscriptions.push(
      // memory leak ahead !
      timer(0, 1000)
        .subscribe(() => this.counter++),
    );
  }

  ngOnDestroy(): void {
    unsubscribe(this.subscriptions);
  }

}
Enter fullscreen mode Exit fullscreen mode

Now, when your component is destroyed, you are safe from memory leaks as you have properly unsubscribed from the RxJS observable.

Top comments (5)

Collapse
 
zhhb profile image
Ten

why do like this:

destroy = new Subject()
// some where you do subscribe
someObservable.pipe(takeUnitl(this.destroy)).subscribe(....)

ngOnDestroy(){
this.destroy.next();
this.destroy.complate();
}
Collapse
 
gempain profile image
Geoffroy Empain

That's a nice way to do it as well :)

Collapse
 
martinspire profile image
Martin Spierings

pipe(take(1)) also helps but you can also make an onDestroyService that automatically runs unsubscribe on your subscriptions. If you always add them to this.subscriptions, it will work fine.

Collapse
 
danielsc profile image
Daniel Schreiber

This is an important pattern. For me this library solved this pretty elegantly: github.com/ngneat/until-destroy

Collapse
 
gempain profile image
Geoffroy Empain

Interesting library ! I like the .pipe(untilDestroyed(this)) pattern. The annotation is also quite clean as well. The only disadvantage of an annotation is that you don't directly see the link between the unsubscribe and the actual code. The pipe forces you to manually unsubscribe, IMO makes the code easier to maintain, and is syntactically nicer than pushing into the array. Good one :)