Search code examples
vue.jsvuejs2vuexvue-router

Vue-router : Uncaught RangeError: Maximum call stack size exceeded


I’m trying to use router.beforeEach() to check a condition before every transition if the user is logged in or not, if not I would like to redirect him to the login page. I’ve tried:

 router.beforeEach((to, from, next) => {
    const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
    const currentUser = store.state.currentUser;

    if(requiresAuth && !currentUser) {
        next('/login');
    } else if(to.path == '/login' && currentUser) {
        next('/home');
    } else {
        next();
    }
});

but return an error : Uncaught RangeError: Maximum call stack size exceeded and this my route:

export const routes = [
{path: '/', component: Main ,meta: {requiresAuth: true},children:[
    {path: '/project', component: project , meta: {requiresAuth: true} },
    {path: '/calendrier', component: calendar, meta: {requiresAuth: true} },
    {path: '/setting', component: setting, meta: {requiresAuth: true} },
    {path: '/client', component: client, meta: {requiresAuth: true} },
    {path: '/detail/:id', name: detail , component: detail, meta: {requiresAuth: true} },
    {path: '/membre', component: membre, meta: {requiresAuth: true} },
    {path: '/test', component: test, meta: {requiresAuth: true} },
    {path: '/projectemploye' , component: projectemploye, meta: {requiresAuth: true} },
    {path: '/Chefprojet', component: chef, meta: {requiresAuth: true}},
    {path: '/client/:id' , component: clientdetail, meta: {requiresAuth: true} },
    {path: '*' , component:    require('./components/404.vue').default , meta: {requiresAuth: true}},
    {path: '/home' , component: home , meta: {requiresAuth: true}},
    {path: '/gantt/:id' , component: gantt, meta: {requiresAuth: true}},
    {path: '/reclamation' , component: reclamation, meta: {requiresAuth: true}},
    {path: '/detailleReclamation/:id' , component: DetailleReclamation, meta: {requiresAuth: true}},
    {path: '/profile/:id' , component: profile , meta: {requiresAuth: true}},
    {path: '/task/:id' , component: task, meta: {requiresAuth: true}},
    {path: '/taskdetail/:id' , component: taskdetail, meta: {requiresAuth: true} }
    ]
 },
{path: '/login', component: Login},


 ];

Solution

  • The route whose path is *:

    1. must not be a child of any other route
    2. must be last in the routes array
    3. must not have requiresAuth: true in its metadata

    The root route / must not have requiresAuth: true in its metadata.

    In your case there is no need to list all routes as children of the root route.

    If all your routes are protected and only /login is public - then it would be better to switch your logic from positive to negative. This means that rather then putting requiresAuth: true on all routes except /login you should put public: true in /login and leave all other routes with empty metadata.

    Then instead of checking for meta.requiresAuth you will check for !meta.public