frenchbaguette
frenchbaguette

Reputation: 1339

Cannot get cookie in vue-router to work. Undefined "this"

The problem is that I cannot get cookie in vue-router. When I try to do this: this.$cookie.get('token'); I get this undefined. Even though I can use this.$cookie in vue components. This is my code snippet:

Vue-Router:

This is a function to check if I get token from cookie (but it doesnt work):

function isLoggedIn (to, from, next) {
  console.log(this.$cookie.get('token'));
}

And this is the route and I use that isLoggedIn in it:

{
  path: '/',
  name: 'login',
  component: Login,
  beforeEnter: isLoggedIn()
},

Maybe someone knows how to get that cookie ? It it setted up in vue component correctly just don't know how to pass it to vue router.

EDIT So by using Vue.cookie.get('token'); I get that next is not a function. This is the current function:

function isLoggedIn (to, from, next) {
  if(Vue.cookie.get('token')) {
    next({name: 'game'});
  } else {
    next();
  }
}

Okay so when I added this function directly into route like this it worked:

{
  path: '/',
  name: 'login',
  component: Login,
  beforeEnter: (to, from, next) => {
    if(Vue.cookie.get('token')) {
      next('/game');
    } else {
      next;
    }
  }
},

Upvotes: 1

Views: 2130

Answers (2)

Steve Holgado
Steve Holgado

Reputation: 12089

If you are using the vue-cookie plugin from npm then you will need to use this syntax outside of components:

function isLoggedIn (to, from, next) {
  console.log(Vue.cookie.get('token'));
}

With regards to your next is not a function error, this is because you are invoking your function with no arguments, isLoggedIn(), rather than passing the function reference, isLoggedIn, which will be invoked by the router with the appropriate arguments.

Try this instead:

{
  path: '/',
  name: 'login',
  component: Login,
  beforeEnter: isLoggedIn // No parentheses here
},

I hope this helps.

Upvotes: 1

Ohgodwhy
Ohgodwhy

Reputation: 50798

If you look at the typings, you'll see that both to and from are Route's. Here's their interface declaration:

export interface Route {
  path: string;
  name?: string;
  hash: string;
  query: Dictionary<string | (string | null)[]>;
  params: Dictionary<string>;
  fullPath: string;
  matched: RouteRecord[];
  redirectedFrom?: string;
  meta?: any;
}

If look at the Definition of BeforeEnter:

beforeEnter?: NavigationGuard;

If you look at the Definition of NavigationGuard:

export type NavigationGuard<V extends Vue = Vue> = (
  to: Route,
  from: Route,
  next: (to?: RawLocation | false | ((vm: V) => any) | void) => void
) => any

So as we can see, the beforeEnter returns a closure that exposes 3 methods to us: (to, from, next).

As we can see the typings of both to and from are just Route Interfaces and next is a function that we pass arguments into, we can safely determine that the scope of this is indeed, undefined.

So you can either define it in the meta of the Route declaration and access it with this.$meta.cookies, or you can import the cookie package directly and use it with cookies.get('token') or you can augment the return type of the beforeEnter method:

beforeEnter: (to, from, next) => isLoggedIn(to, from, next, $cookies)

You still, cannot, use the in component guards as they do not expose this to you because they execute before the component has been created

Upvotes: 1

Related Questions