Ionic - Global navigation change event

Hi,

I am wondering if there is any way to subscribe/listen to a master change event is my App class. There is some behavior that I want to occur on every nav change, and it would be tedious to do this on every single NavController in my app. Thanks in advance.

2 Likes

@zakton5 I’m looking for the same thing for auth purposes. Have you found a solution?

FYI, I found this related question but there are no responses there yet either unfortunately:

https://forum.ionicframework.com/t/listen-for-navigation-events/52437

this works for me in beta 10. Nice for logging (Google Analytics) :slight_smile:

this.nav.viewDidEnter.subscribe((view) => {
    console.log(view.instance.constructor.name);
});

See:
https://github.com/driftyco/ionic/blob/master/src/components/nav/nav-controller.ts#L236

2 Likes

Are you sure this works? I tried it but I do not get events when navigating inside child views, probably because the nav controller that is injected to them is a copy of the root nav controller and the same one as the one we have subscribed to. Try hooking the event on the root view and then loading a Tabs pages and do navigation in there to understand what I mean.

In my scenario with just a sidemenu it works well. I havent tested it with tabs or child views.
I have added the subscribe in my App Component

class MyApp {
    @ViewChild(Nav) nav: Nav;
    rootPage: any;

    constructor(private platform: Platform, private config: Config) {


    }
    ngAfterViewInit() {
        this.nav.viewDidEnter.subscribe((data) => {
            if (this.platform.is('cordova')) {

                GoogleAnalytics.startTrackerWithId(this.config.analytics_trackingId).then(() => {
                    GoogleAnalytics.trackView(data.instance.constructor.name)
                })
            }
        });

    }
}
2 Likes

I tried your solution @hackfrag and it definitely works. The only thing I need now is a way to cancel navigation if the user has not completed the entire form that is on the page. Any ideas on how to do this?

There are undocumented lifecycle events on App (I just sent a PR for the docs, so hopefully will be added soon). So you can do this in your app component:

import {App} from 'ionic-angular';
...
export class MyApp {
  rootPage = HomePage;
  
  constructor(app: App) {
    app.viewWillEnter.subscribe(
      () => console.log('view about to be entered')
    )
  }
}

There are events emitted for viewWillEnter, viewDidLoad, viewWillUnload, viewWillLeave, viewDidEnter and viewDidLeave.

8 Likes

I agree with @amuramoto.
And you can also use livecycles on all pages in the same way:

export class MyApp {
  rootPage = HomePage;
  @ViewChild(Nav) nav:Nav
  constructor() {
    this.nav_app.viewDidEnter.subscribe(
      view => console.log("Current opened view is : " + view.name);
    )
  }
}
3 Likes

@amuramoto thanks, buddy

M looking this… and you give me…
:+1:

One warning though: view.name will not work after code minifier/uglifier runs.

Yes. I know.
They mention it also here: Get current page/ view name in RC0 returns "t"

I already find a bug registered for that on github but i can’t find it back to share the link.

Thanks!!! works as i need it.

A post was split to a new topic: Does viewDidEnter fire after animation is completed?

In case anyone is curious about animations, setRoot and push (on the this.nav object) return a promise that resolves when completed. I use this, and then use Events to publish an event, subscribing to it in the other view

1 Like

Hi bro, how are you?

Thanks by the useful answer.

Let me ask you something: there is a way to listen the page changes even after these pages are loaded?

Apparently, in my recent tests with Ionic 3, the lifecycles works for ViewControllers only if they arent loaded yet, but it isnt fired when I, for example, on feed page, change to profile page from tab button and back to feed page by tab click. So, when I get back to already loaded feed page, the lifecycle event viewWillEnter and viewDidLoad arent fired.

Do you know how can I listen every page change, regardless of whether it has already been loaded or not?

Thanks in advance