Akond
Akond

Reputation: 9

Infinite loop with vue router beforeEach and children paths

When i use beforeEach with children paths debug console show this error: vue-router.esm.js?8c4f:2079 RangeError: Maximum call stack size exceeded

import Vue from 'vue'
import VueRouter from 'vue-router'
import LoginMixin from '@/mixins/LoginMixin.js'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: require('@/views/Home.vue').default,
  },
  {
    path: '/login',
    name: 'login',
    meta: { layout: 'centered' },
    component: () => import('@/views/Login.vue'),
  },
  {
    path: '/register',
    name: 'register',
    meta: { layout: 'centered' },
    component: () => import('@/views/Register.vue'),
    children: [
      {
        path: 'user',
        component: () => import('@/components/RegisterForm.vue'),
      },
      {
        path: 'company',
        component: () => import('@/components/CompanyForm.vue'),
      }
    ]
  },
]

//creamos la instancia router modo history(urls amigables)
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to, from, next) => {
  if (to.path != '/login' || to.path != '/register/user' && LoginMixin.methods.loginMixinCheckAuth() == false) {
    //if not logead and join to other page distinc of login or register redirect to login
    next('/login')
  }
  else {
    next()
  }
})

I dont know what is bad, the syntaxis is fine and function LoginMixin.methods.loginMixinCheckAuth() is working good (i tested without the function and result is the same).

Upvotes: 0

Views: 1969

Answers (1)

Klemen Tusar
Klemen Tusar

Reputation: 9699

Hmm at first glance I'd try to make this convoluted if in your beforeEach method simpler. Try to add something like requiresAuth: true to the meta of all your routes that require a logged in user.

In a sense you want something like this in your routes:

  // ...
  {
    path: '/users/:userId(\\d+)/edit/',
    name: 'EditUser'
    props: true,
    meta: {
        requiresAuth: true, // <-- add this meta flag against which you check later in beforeEach
    },
    component: () => import(/* webpackChunkName: "user-edit" */ '@/views/UserEdit.vue'),
  },
  // ...

And this in your beforeEach:

router.beforeEach((to, from, next) => {
    if (to.matched.some((record) => record.meta.requiresAuth)) { // <-- check for requiresAuth here
        // assuming your login mixin works
        // if I were you I'd store some JWT in localStorage and check that somehow in a vuex getter
        if (!LoginMixin.methods.loginMixinCheckAuth()) {
            next('/login')
        } else {
            next()
        }
    } else {
        next()
    }
})

To answer this in full would be kinda bulky so go and check out how I did that using meta here and implemented a beforeEach rule here

Upvotes: 1

Related Questions