Skip to content

bug: vue router outlet throws when a superseded page mounts after the route moved on #31569

Open

Description

@hendriksenremco

Prerequisites

Ionic Framework Version

v8.x, v9.x

Current Behavior

When a page in IonRouterOutlet mounts its <ion-page> after the route has already moved on to a newer page, and before the newer page has mounted its own <ion-page>, the late page's registerCallback calls handlePageTransition(). That function reads the current route, so it runs the transition for the newer page, whose ionPageElement is still undefined. It logs the "does not have the required <ion-page> component" warning for the newer page and then throws:

TypeError: Cannot read properties of undefined (reading 'classList')
    at isViewVisible (IonRouterOutlet.ts)
    at handlePageTransition (IonRouterOutlet.ts)
    at enteringViewItem.registerCallback (IonRouterOutlet.ts)
    at registerIonPage (IonRouterOutlet.ts)
    at IonPage.mounted (IonPage.ts)

This can happen whenever pages mount asynchronously (async components, async setup) and the user navigates again before the first page has finished.

Expected Behavior

A page that registers after the route moved on should not run the transition for the newer page. The newer page should run its own transition once its <ion-page> registers, without the warning or the error.

Steps to Reproduce

  1. Render an IonRouterOutlet with the routes /, /list and /detail, where /list and /detail are async components (defineAsyncComponent) that resolve on demand.
  2. Navigate to /list, then to /detail before either component has loaded.
  3. Let /list finish loading before /detail.
  4. Observe the missing <ion-page> warning for /detail and the TypeError above.

Code Reproduction URL

No standalone reproduction app yet. The linked PR adds a unit test to packages/vue/test/base/tests/unit/routing.spec.ts that follows these steps with the real router and outlet and fails on main with this TypeError.

Ionic Info

Seen with @ionic/vue 8.8.5 in a Nuxt + Capacitor app (not an Ionic CLI project, so no ionic info output). The same code is unchanged on main (@ionic/vue 9.0.7).

Additional Information

Suggested fix: in the registerCallback set up by setupViewItem, only call handlePageTransition() when the view item for the current route is the entering item, or when that item has no pending registerCallback. I will open a PR with this change and the test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions