Ridvan Sumset
Ridvan Sumset

Reputation: 548

Infinite loop for vue-router's beforeEach method

I want to replace one of the params of to if to's name is a specific one and I have no idea why this doesn't work.

export const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  scrollBehavior() {
    return { x: 0, y: 0 };
  },
  routes: [
    {
      name: 'Details Page',
      path: 'details/:name/:id',
      component: () => import('@/views/Details.vue'),
      meta: {
        encode: true,
      },
    },
    // other routes... (none of them has encode = true)
  ]
});

function needsEncode(route) {
  return route.meta && route.meta.encode;
}

router.beforeEach(async (to, from, next) => {
  if (to.name === 'Details Page' && needsEncode(to)) {
    const toEncoded = Object.assign({}, to, {
      meta: {
        encode: false,
      },
      params: {
        name: encodeURIComponent(to.params.name),
        id: to.params.id,
     },
    });
    return next(toEncoded);
  }
  return next();
}

What am I doing wrong?

Upvotes: 0

Views: 324

Answers (1)

Phablulo Joel
Phablulo Joel

Reputation: 329

Please don't store state in the meta property. Instead you can check if the name is already encoded:

function needsEncode(route) {
  return route.meta && route.meta.encode && ( // <-- changes start here
    decodeURIComponent(to.params.name) === to.params.name
  ) // <-- changes ends here
}
router.beforeEach(async (to, from, next) => {
  if (to.name === 'Details Page' && needsEncode(to)) {
    const toEncoded = Object.assign({}, to, {
      // remove meta
      //meta: {
      //  encode: false,
      //},
      params: {
        name: encodeURIComponent(to.params.name),
        id: to.params.id,
     },
    });
    return next(toEncoded);
  }
  return next();
}

If decodeURIComponent(to.params.name) is equal to the name, then it's not encoded yet and you can proceed to encode it.

Upvotes: 1

Related Questions