Router async beforeEach triggers two routes

Viewed 711

I'm trying to wait for an asynchronous response in my route guard. The problem is that two routes are hit.

When the page is loaded, the / route is triggered instantly, followed by my target route

router.beforeEach(async (to, from, next) => {
  await new Promise(resolve => {
    setTimeout(resolve, 500)
  })
  next()
})

or

router.beforeEach((to, from, next) => {
    setTimeout(next, 500)
  })
})

In my log I see two entries when visiting /foo, first / then /foo after 500ms. I'm expecting to see only the latter:

setup(props, { root }) {
    const hideNav = computed(() => {
      console.log(root.$route.path)
      return root.$route.meta?.hideNav
    })

    return {
      hideNav
    }
  }
})

I'm using vue@2.6.12 and vue-router@3.4.9

2 Answers

I'm not sure but this how I guard my route in a Vue component hope this helps you

 beforeRouteEnter(to, from, next) {
    if (store.getters.isAuthenticated) {
      Promise.all([
        store.dispatch(FETCH_ARTICLE, to.params.slug), 
        store.dispatch(FETCH_COMMENTS, to.params.slug)
      ]).then(() => {
        next();
      });
    } else {
      Promise.all([store.dispatch(FETCH_ARTICLE, to.params.slug)]).then(() => {
        next();
      });
    }
  },

Have you tried using beforeEnter?
This way you can specify which routes are going to execute your function

Like this code below:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})
Related