JK2018
JK2018

Reputation: 489

vue router 4 next() callback warning

I have unsucessfully been trying to fix this vue-router warning :

The "next" callback was called more than once in one navigation guard when going from "/" to "/". It should be called exactly one time in each navigation guard. This will fail in production.

I have read the official doc (https://next.router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards) but I keep getting infinite next loop when making the suggested changes, so I am obviously doing something wrong.

What I would like to do is : Have non authenticated users only be able to navigate to "/" route. and get redirected to "/" if they try to enter a protected route. Have authenticated users directly land on "/mapping" and skip "/" route. They can then nav to any protected routes.

I verify auth with "let user = projectAuth.currentUser".

Thanks in advance for your tips

import { createRouter, createWebHistory } from 'vue-router'
import Mapping from '../views/Mapping.vue'
import Home from '../views/Home.vue'
import TestDthree from '../views/TestDthree.vue'
import Testpage1 from '../views/Testpage1.vue'
import { projectAuth } from '../firebase/config'



// auth guard or route guard
// requires to be authenticated
const requireAuth = (to, from, next) => {
  let user = projectAuth.currentUser
  if(!user){
    next({name:'Home'})
  }
  next()
}


// no auth needed
// bypassed Home for any logged in user
const requireNoAuth = (to, from, next) => {
  let user = projectAuth.currentUser
  if(user){
    next({name:'Mapping'})
  }
  next()
}







const routes = [ 
  {
    path: '/',
    name: 'Home',
    component: Home,
    beforeEnter: requireNoAuth
  },
  {
    path: '/mapping',
    name: 'Mapping',
    component: Mapping,
    beforeEnter: requireAuth
  },
  {
    path: '/testpage1',
    name: 'Testpage1',
    component: Testpage1,
    beforeEnter: requireAuth
  },
  {
    path: '/loadLegacyData2',
    name: 'LoadLegacyData2',
    component: () => import( '../views/LoadLegacyData2.vue'),
    beforeEnter: requireAuth
  },
  {
    path: '/testmap',
    name: 'TestDthree',
    component: TestDthree,
    beforeEnter: requireAuth
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})


export default router

Upvotes: 10

Views: 9439

Answers (2)

Orbis
Orbis

Reputation: 475

Just add returns in requireAuth:

  const requireAuth = (to, from, next) => {
    let user = projectAuth.currentUser
    if(!user){
      next({name:'Home'})
      return
    }
    next()
    return
  }

Or

  const requireAuth = (to, from, next) => {
      next(projectAuth.currentUser ? to : {name:'Home'})
      return
  }

Upvotes: 16

jeremy castelli
jeremy castelli

Reputation: 1260

you have to check if you are not already on the page, otherwise it will loop indefinitely. Something like this

const requireAuth = (to, from, next) => {
    let user = projectAuth.currentUser
    if(!user && from.name !== 'Home'){
       next({name:'Home'})
    }
    next()
}

Upvotes: 0

Related Questions