3

Hi am very new to Angular. I have around 4 database queries and each of them are Subscriptions(rxjs/Rx). So I know I need to unsubscribe each of my subscriptions to save memory leakage. How can I optimise the calling? I mean, I don't want to call each subscription and unsubscribe one by one. I wanna do it all the unsubscribe in one call. Sorry if its a stupid question. Any idea guys? Thanks in advance

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
blackdaemon
  • 755
  • 5
  • 19
  • 44
  • 1
    Reading this might help: https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87 – cartant Mar 08 '17 at 06:50
  • 1
    You don't need to unsubscribe http://stackoverflow.com/questions/35042929/do-you-need-to-unsubscribe-from-angular-2-http-calls-to-prevent-memory-leak – Daniel Ormeño Mar 08 '17 at 06:53

3 Answers3

5
subscriptions = Subscription[];

someMethod() {
  this.subscriptions.push(http.get(...).map(...).subscribe(...));
}

ngOnDestroy() {
  this.subscriptions.forEach(s => s.unsubscribe());
}

When an observable completes, unsubscribing is redundant. Unsubscribing is only necessary for observables that continueally emit events without completing.

If you only want to receive a single (or otherwise limited number of events) you can control when the observable you subscribed to completes by using an operator like take(x), then after x events the observable will complete.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    I was writing a comment about the redundancy of unsubscribing but you were faster in your edit :). Some good read about that : http://stackoverflow.com/a/41177163/7447071 – mickdev Mar 08 '17 at 06:54
  • Goold link (like the one from carcant). – Günter Zöchbauer Mar 08 '17 at 06:55
  • @Günter, I understand that when a stream is completed that it unsubscribes in the teardown and in that case we don't need to unsubscribe manually. But, I am unclear about when an http call is initiated and the user navigates away from the view before the call returns or if it never returns at all. I heard that if that happens then a leak is created, can you pls confirm or deny? – Thibs Apr 04 '17 at 00:37
  • I don't think this is a problem, but I would need to see a concrete code example. – Günter Zöchbauer Apr 04 '17 at 02:56
1
export class BaseComponent implements OnDestroy {

  protected alive$:  Subject<void> = new Subject<void>();
  ngOnDestroy(): void {
    // console.log("unsubscribing base component");
    this.alive$.next();
    this.alive$.complete();
  }
}

export class EveryComponent extends BaseComponent {
  this.AllObs1$.takeUntil(this.alive$).subscribe(...);
}
0

There's also another interesting way to do that :

@Component({ ... })
export class SomeComponent implements OnInit, OnDestroy {
  private componentDestroyed$ = new Subject();

  ...

  ngOnInit() {
    this.yourObs1$.takeUntil(componentDestroyed$).subscribe(...);
    this.yourObs2$.takeUntil(componentDestroyed$).subscribe(...);
    this.yourObs3$.takeUntil(componentDestroyed$).subscribe(...);
    ...
    this.yourObsX$.takeUntil(componentDestroyed$).subscribe(...);
  }

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

Here, you don't even need to keep track of a subscription and the way you read is more dev friendly (I think).

Ben Lesh explained it on Medium and I like this way to unsubscribe !

maxime1992
  • 22,502
  • 10
  • 80
  • 121