Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsubscribe in subscribe callback function?

Tags:

angular

rxjs

I've been looking around for a simple way to avoid the memory leaks I've read about caused by failing to unsubscribe. Most of the time I'm just wanting the ONE response from my backend. And then I'll want to unsubscribe. So why not call it in the callback?

  onSubmit(){
    var subscription = this.puzzleService.login(this.nameoremail, this.password).subscribe( success =>{
      if(success){
        this.router.navigate(['/puzzles']);
      }
      else{
        this.message="Login failed. Please try again.";
      }
      this.loading=false;
      subscription.unsubscribe();
    });
    this.loading=true;
  }

Note the assignment of the subscription to a local variable. This local variable is then locked inside a closure and told to unsubscribe when its work is done. No class variables, no takeUntil, nothing else.

It compiles and runs without error. I'm not familiar enough with the debugger to determine if the observable object is actually destroyed and subsequently garbage collected.

Is there something I'm missing? Can someone more familiar with the debugger correct me? Because if this works I'm going to be doing this everywhere. Except in my pollWords() function...

This seems much simpler than other solutions I've seen advocated. I'd think I didn't even really need the closure, as when I look at it in the debugger I see "_this" is the closure for "this" and "this" is actually the observable. So if there was some way to prevent the munging that is happening to "this" then I could call "this.unsubscribe()" and be done. Not that an object reference closure is a horrible thing...

References:

Angular/RxJs When should I unsubscribe from `Subscription`

Rxjs Observable Lifecycle

like image 449
John Gilmore Avatar asked Nov 08 '18 21:11

John Gilmore


People also ask

Does TakeUntil unsubscribe?

We can simply call the unsubscribe() method from the Subscription object returned by the subscribe() method in the ngOnDestroy() life-cycle method of the component to unsubscribe from the Observable. There is also a better way to unsubscribe from or complete Observables by using the takeUntil() operator.

Does observable complete unsubscribe?

Note that when an observable emits a complete event, subscriptions will automatically be unsubscribed, and that certain frameworks using RxJS may also handle unsubscriptions automatically in certain cases. In all other cases, we must handle unsubscribing ourselves.

Does RxJS first unsubscribe?

The RxJS first() operator waits until the first value is emitted from an observable and then automatically unsubscribes, so there is no need to explicitly unsubscribe from the subscription.

How do I unsubscribe from RxJS?

Unsubscribing Manually RxJS provides us with a convenient method to do this. It lives on the Subscription object and is simply called . unsubscribe() .


2 Answers

A more RxJS-ish way of doing what you want is to make use of the take operator, like this:

this.puzzleService.login(this.nameoremail, this.password).pipe(
  take(1)
).subscribe(success => {
  // ...
});

This will make the observable emit exactly one value and then complete it.

However, @Picci is totally right that if your login method returns a result from a HttpClient request, you don't need to unsubscribe manually (nor use take, for that matter).

like image 195
Jeto Avatar answered Sep 18 '22 14:09

Jeto


Unsubscribing is important to avoid memory leaks, but it maybe not so important if you are "just wanting the ONE response from backend".

What I mean is that if, behind your this.puzzleService.login you are using the Angular http service, than you do not have to worry about unsubscribing since the service itself unsubscribes as soon as it gets the response from the backend, or an error occurs.

Unsubcribing is important when you face Observable streams which emit, by their nature, more than one value, and this is not the case of an http call but may be the case of web-sockets streams or other kind of streams.

This article from Ben Lesh, top contributor if not lead of RxJS, casts some light on the topic.

like image 25
Picci Avatar answered Sep 20 '22 14:09

Picci