Events and Page lifecycles

TL;DR:
Pages aren’t destroyed when setRoot() is called. This messes with events.subscribe() on these pages as the handler functions are called as many times as there are supposedly destroyed pages.

in more detail:
My app is very simple. There is a HomePage. From there you can go into two other pages (both with this.nav.push();), on one there is a simple gallery where you can look at pictures, on the other page you take a picture and then pick a category for the thing on the picture. Once that is done, I do a this.nav.setroot(HomePage). In the HomePage I have a button that causes the app to upload all the pictures that haven’t been uploaded yet. Once uploadig is finished, the uploader service firesan event. HomePage subscribes to that event (in the constructor).

The problem is: Once I’ve taken a couple of pictures and navigated back to the HomePage, the action defined in subscribe of the Homepage is fired multiple times.

To check if this comes from there simply being multiple instances of HomePage, I’ve added a random number to HomePage in the constructor that is logged to the console whenever there is any action going on the HomePage. So I tested it and, lo and behold, there are multiple instances of HomePage. That’s why my app has been acting weird (to be precise: in the subsciption I’ve presented a Toast, and that toast was shown a couple of times, depending on how many HomePages there were, this even prevented me from going to another Page until I’ve checked every single of the Toasts).

So … I was really wondering what I can do here. I was trying out the whole Ionic events and was pleasantly suprised about how well it worked, but apparently I was endeared too early.

The weird thing is DOC says “They [pages] are destroyed when removed from the navigation stack (on pop() or setRoot())”.
But apparently that is not correct as I am doing the setRoot() back to HomePage, and all the older HomePage pages are still alive and triggered by my custom events.

How come my pages aren’t destroyed when I call setRoot()?

For me it does get destroyed, i have a few Rxjs and EventEmitter subscriptions, i think what u may lack is unsubscribing in the destroy method:

class ObservableHolderPage {
  constructor(private someService: SomeService) {
    this.observable = this.someService.someSubject.subscribe(() => { ... })
  }
  ngOnDestroy() {
    this.observable && this.observable.unsubscribe()
  }
}

Thanks for your reply.

I did some tests with ngOnDestroy(), but that event handler or whatever you wanna call it is never called. My Pages do not get destroyed, although they should. I have no idea why.

Oh now i remember, Ionic 2 caches the pages in order to reduce load times for consecutive access to pages, what you need isn’t ngOnInit() but ionViewDidEnter() or something like that, look here in the lifecycle events section:

I’ve tried all of the lifecycle events, none of them fired, at all. That is more than strange.

It’s repo’s issue time, file an issue to the ionic team: http://ionicframework.com/submit-issue/

Did anything ever come of this? I’m finding that whenever I’m on a root tab page, then push to another page, then back, I’m creating multiple instances of the root tab page, so my events are firing as many times as I have left and then come back to my tab root page.

Have you tried popTo, seems to have worked for my project.

I had a SearchPage that created a Modal, and onDidDismiss would call setRoot to the Home Page,
this ModalPage was publishing an event and the HomePage was subscribing to the event,
I found that each time I added a search result item it would increment the instance of the result

So the first time you did a search and added the result it seemed like everything was working.
But if you added a second result, it would appear twice in the list on the HomePage, etc etc

So I tried wrapping the subscription (at HomePage) in all the different lifecycle hooks both Ionic and Angular – but it didn’t work as you said)

But then I read in all the forums that too many setRoot calls causes the constructor/page to fire multiple times (Constructor and lifecycle events fires twice)

So I replaced setRoot with popTo, and it now works as expected.