By using take, takeUntil, or takeWhile, will my observables get cleaned up the same way as unsubscribe?


#1

The title is my basic question. The below is just more context.

Recently I’ve been working with push notifications in our Ionic app using the Ionic.io push service. That API has one endpoint to create a push with which queues it up for sending. But then it has another endpoint you can poll to see the status of the push. I wanted to create the push notification based on a user action, then subscribe to the endpoint with the status to see if it goes through or errors out. Meanwhile the user may navigate on to another part of the app. So I didn’t want to use OnDestroy this time to unsubscribe. I decided instead to do a takeUntil to determine when to stop.

Is this a good approach? I am still pretty new to Observables so I want to make sure this won’t create an Observable in memory that’s just hanging out somewhere.


#2

A friend of mine ran across a pull request in RxJs that addressed this issue. So the answer is yes if you use one of the takeX functions you are safely unsubscribed at the end.


#3

The Observable completes after emitting (at most) twice if you attach .take(2), and your Observable will be done after completion. On the other hand, if it emits once, then waits for a loooong time, and then emits again later, you might not be on the page anymore, but your variable still changes, so be careful. But you probably already knew this.

The bigger deal in your question is your mention of OnDestroy. That does not work the same way in Ionic as it does in Angular, and I don’t recommend using it at all, for anything. Instead, if you want to destroy a page, pop it off the nav stack. If you can’t do that naturally, assume it’s around forever. This means that you might need to subscribe to an Observable in IonViewWillEnter() and unsubscribe in IonViewWillLeave() to support users who move forward and backward through your app with the back button. I try to use the async pipe as much as possible for this reason, and to use the word “subscribe” almost never in my code. (I actually only use subscribe in providers that have no associated DOM, so I keep subscribe away from the nav stack completely.)


#4

In my case, we are actually using Firebase as the backend and each connection to it is a Websocket connection so we use the AngularFire2 library that returns Observables. So we have to subscribe in pages if we want any data in them. But since “take” is safe that means it is perfectly safe to subscribe to these even if the page hangs out on the nav stack.


#5

The examples in the af documentation rely on the async pipe, not on the use of subscrptions in the controller.


#6

Refer here. It’s still safe to use take.


#7

If there’s no template, as in the example you linked, they use subscribe. And in the example immediately below the one you linked, where there’s a template, they use async. I’ve tried to follow that practice in my own code.


#8

The bigger deal in your question is your mention of OnDestroy. That does not work the same way in Ionic as it does in Angular, and I don’t recommend using it at all, for anything. Instead, if you want to destroy a page, pop it off the nav stack. If you can’t do that naturally, assume it’s around forever.

Let’s examine your stance. The page is around until you pop it off the nav stack. Yes, I agree. I think you’re right about that. Now from this, you then conclude that if you don’t pop it off the nav stack, the page is around “forever” which I will assume is a hyperbolic way to say as long as your app is running.

Then you reason that because of this, OnDestroy should not be used “at all, for anything.” You furthermore conclude “use the word “subscribe” almost never.”

My response to this is we’ve now named multiple ways that both the page doesn’t need to hang around during the entire app lifetime and that any Subscriptions to Observables don’t need to hang around either.

We’ve collected the following methods:

  1. unsubscribe in OnDestroy and pop the page off the nav stack
  2. Use take, takeUntil, or takeWhile on the observable

I’ll also mention you can unsubscribe from the Observable at any other reasonable point.

Finally, there are some Observables like the Angular Http get and post methods, that will only emit one response anyway, so there’s no need to unsubscribe AFAIK.

For these reasons, while I appreciate the thoughts, I just don’t agree that I should never use OnDestroy, at all, for anything or that I should use the word subscribe almost never in my code.


#9

I described what I do, and why. I don’t think I told you how to code, in anything I posted. I’m not trying to have an online slapfight here, and I don’t know why you came at me the way you did. But there is a difference between ngOnDestroy() and other Angular lifecycle hooks. Hooks like ngOnInit() and ngAfterViewInit() are sandwiched within Ionic lifecycle events that are guaranteed to happen, like IonViewDidLoad(). ngOnDestroy() will happen if/when Ionic gets around to it. I don’t see the safety of putting cleanup code in a section like that. You might be fine with it of course, though I wonder if you’ve simulated malicious use of your app. Or what if the first version of your page is not yet destroyed before the second version is created? Will the Ionic Framework code always guarantee that won’t pose you a problem? Maybe it does, but that’s handing over a lot of my personal destiny to a framework that isn’t fully stable. Anyway, best wishes.