MitsuhaKitsune / vuex-webextensions

A Vuex plugin to share store through webextensions components
MIT License
83 stars 30 forks source link

Can't get values from store in files that are not *.vue #35

Closed notjasonknott closed 3 years ago

notjasonknott commented 4 years ago

I'm trying to access store.getters.user.token to check if there is an active user state. If there is, I want to redirect the user to the app, but if there isn't then they need to log in.

routes.ts

import store from '../../store';
...
  {
    path: '/',
    component: Portal,
    children: [
      {
        path: '',
        name: 'login',
        component: Login,
        beforeEnter(routeTo: any, routeFrom: any, next: any) {
          if (store.getters.user.token) {
            next({ name: "home" });
          } else {
            next();
          }
          next();
        }
      },
      ...
    ],
  },

In this context, store.getters.user.token is undefined because the user object looks like this:

Object 
  __ob__: At {
    value: {…}, dep: ct, vmCount: 0} 
  __proto__: Object

Whereas, in any *.vue file, the store.getters.user.token reveals the token:

Home.vue

<template>
  <div>
    <p>Home</p>
    {{this.token}}
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  computed: {
    token() {
      return this.$store.state.user.token;
    },
  },
};
</script>

<style lang="scss" scoped>
p {
  font-size: 20px;
}
</style>

Home.vue showing the token: image

But, when I console.log(store.state) in routes.ts I get the user object containing all the right values! image

My hypothesis is that it has something to do with the object being loaded asynchronously, but I am not sure how to fix that issue. Do you have any ideas for what I could do?

Update I am currently using a setTimeout to fix this issue. If someone could think of a more ideal solution, I'm all ears!

  {
    path: '/',
    component: Portal,
    children: [
      {
        path: '',
        name: 'login',
        component: Login,
        beforeEnter(routeTo: any, routeFrom: any, next: any) {
          setTimeout(() => {
            if (store.getters.isLoggedIn) {
              next({ name: "home" });
            } else {
              next();
            }
            next();
          }, 300)
        }
      },
      {
        path: '/register',
        name: 'register',
        component: Register,
      },
    ],
  },
MitsuhaKitsune commented 3 years ago

The issue it's confusing, but I think that I understand fine.

You are using vuex-webextensions with persistent states in your config for auth things, but beforeEnter logic it's executed before localstorage data read.

Unafortunally, the local storage read are async and have a bit of delay on initialization, so you should wait for this initialization before do any action that require saved states on it.

To workarround this situations, I implemented the VWE_ReplaceState mutation on https://github.com/MitsuhaKitsune/vuex-webextensions/commit/42744059bf86ceaf72d599a3f1e222f30e8105c1 and you can hook this mutation to do your initialization logics ensuring that data are fully loaded.

I gona close the issue because isn't it as it has explained, but I gona document the wait for VWE_ReplaceState mutation before do any action that require states stored on localstorage.

If I didn't understand fine, just tell me and I reopen this, but I think that the problem are there.