Can I listen for ion-nav events from within a view?

I have a project that is Ionic Vue 6, and I’m using the composition API.
In this project I have an Ion-Nav component that shows various different views in its hierarchy. I am able to add an event listener to the ion-nav component directly:

<ion-nav
          :root="Home"
          :id="nav"
          @ionNavDidChange="navViewChanged()"
        />

However I’d like to be able to listen for these events from within the views themselves. I get a reference to the nav from within these views that allows me to call push() and pop() methods on the nav:

const nav = document.querySelector("#nav");
nav.push(AnotherView, {id:1, text: "hello world});

I can’t seem to be able to add an event listener though. The following doesn’t work.

nav.addEventListener("ionNavDidChange", ()=>{
   //Do something here
})

Am I going about this in completely the wrong way?

Thanks.

one solution is to just emit the change event from the top level and have the other component listen for the event

Almost works @aaronksaunders, but there doesn’t seem to be a way to get the type of the active view from the ion-nav. So I’ve set up tiny-emitter as below:

        <ion-nav
          :root="Home"
          :id="nav"
          @ionNavDidChange="navChanged"
        />

and in the navChanged function I want to emit the name of the current view, so I got as far as:

    const navChanged = async () => {
      const activeView = await nav.getActive();
      const path = activeView.component?.__file.split("/");
      const filename = path[path.length - 1].split(".");
      const component = filename[0];
      emitter.emit("navChanged", component);
    };

but sadly the __file property doesn’t exist once the app is distributed to a mobile platform. There must be a more elegant way to do this surely?

then just emit the event in a lifecycle event of the actual component that was rendered

That’s the source of my issue - there isn’t a lifecycle event that occurs on a component when it is becomes top of the navigation stack, except OnMounted which is called the first time the view is pushed to the stack.

For example, if I navigate between components A, B, C and D as follows, I want to listen for whenever component C is at the top of the stack, not just the first time it is mounted.

A 
A > B
A > B > C                    <---notification
A > B > C > D
A > B > C                    <---notification
A > B
A > B > C                    <---notification

there are ionic lifecycle events

1 Like

These don’t get fired in ion-nav. I suspect it’s because my ion-nav component is embedded within an ion-page component:

<ion-page>
    <my-custom-header title="A Page" />
    <ion-content :scroll-y="false">
        <ion-label>Some explanatory text</ion-label>
        <ion-nav :root="MainPage" />
    </ion-content>
  </ion-page>

By the way, I should mention my gratitude for your advice @aaronksaunders.

Can you post a small sample project some where? I think it would be easier to get the help you need to resolve your problem.

I’ve posted an example on codesandbox:

If you check the console, while you can see when Page C is mounted/unmounted, the onIonViewWillEnter event never triggers.

Got the ionNav to listen for the event and extract out the active view. First define the nav like this

<ion-nav
  :root="PageA"
  id="nav"
  class="relative grow fullwidth"
  ref="navRef"
  @ionNavDidChange="handleEvent"
/>

inside the setup code, handle the did change event like this

const handleEvent = async (data) => {
  const nav = data?.target;
  const active = await nav.getActive();
  console.log("Active View => ", active);
  console.log("Active View Name => ", active?.component?.name);
};

See a working example here

1 Like

You’re a legend. As it turns out your initial suggestion would have worked if I’d had my components named. Implemented now with tiny-emitter and it works like a dream, thanks so much for your (extremely quick) help.

glad it worked out for you and thanks for kind words