2

I'm having a hard time passing Data (in this case userInfo-Token) from inside a beforeEach(to, from, next) Vue-Router middleware to the coressponding Vue-Component. I'm working on Vue-SinglePage components files as following:

App.js (entry Point)

<template>
    <div id="app">
        <Navigation/>
        <router-view/>
        <Footer/>
     </div>
</template>

Router.js (router-view)

routes: [
    {
        path: '/',
        meta: {requiresAuth: true}
    }
]

router.beforeEach((to, from, next) => {

    if(to.meta.requiresAuth){
        // getting token form local storage
        const token = localStorage.getItem('id_token');

        // retrieving User Information
        axios.defaults.headers.common['Authorization'] = "Bearer "+  token;
        axios.post('http://localhost:4000/auth').then((result) => {
            next();  // <-- how will the following component be able to work with the result?
        } 
    }
}

Dashboard.js ('./' Component)

export default {
    computed: {
        welcomMsg: () => 'Hello '   + result.userName
    }   
}

What i did so far: I tried a passing the userInfo from Entry-Point -> Router -> Component as properties. However it didnt work due to the information being asynchronos.

I tried to attach the data inside the beforeEach to the meta-Object. But I find myself unable to access the meta-Object inside the Component.

Maybe my approach is totally wrong. In this case: Is there a better way to pass the recieved UserData to Vue Components and make them avaliable there?

Thank you in advance.

Aoke
  • 43
  • 1
  • 6

1 Answers1

-1

I would handle this by using Vuex, which is a state management library.

You'd need to use create a Vuex module and add it to your root Vue instance like so:

const store = new Vuex.Store({
  state: { userData: {} },
  mutations: {
    SET_USER_DATA: (state, data) => state.userData = data,
  }
});

new Vue({     // your root Vue instance
  el: '#app', // or whatever you've bound to root instance to
  store,      // the reference to the Vuex store
  ...         // the rest of the root Vue definition
})

Now, the root Vue instance and all of its internal components will have a reference to the Vuex store via the $store property.

Then you can set the userData in you axios callback by calling store.commit, which will subsequently call the specified mutation in the Vuex Store (this would require that you also have the reference to the Vuex store object in this scope):

axios.post('http://localhost:4000/auth').then((result) => {
  store.commit('SET_USER_DATA', result);
  next();
});

And you can access the userData from any component via the $store object:

export default {
  computed: {
    welcomeMsg() {
      let { userName } = this.$store.state.userData || {};
      return (userName) ? 'Hello ' + userName : '';
    }
  }
}

notice I also updated the welcomeMsg computed to fix the spelling and to not use an arrow function

thanksd
  • 54,176
  • 22
  • 157
  • 150
  • Thank you so much for your time. I didn't know you can do this. I will try it right now an give you feedback. Thanks! – Aoke Mar 15 '18 at 17:42
  • @Aoke, no problem. I did backtrack on my initial answer though. I thought that you could access the Vue instance in the `next` callback, but that's only in the `beforeEnter` navigation guard, not `beforeEach`. I still think using Vuex is a good solution in your case, so I've tweaked it a little. – thanksd Mar 15 '18 at 18:01