I have a vue app using vex to store site wide data I get the user info and put it into the state on the before create life cycle method like so:
const app = new Vue({
el: '#app',
store,
beforeCreate(){
store.dispatch('currentUser');
}
});
In my user module I have a getter that gets the name of the user like below:
const getters = {
getName(state){
return state.user.name;
}
};
In my components I am trying to access the getter to display the name of the user in the component. When I look into the Vue Chrome dev tools the getter is not undefined, but when I console log the getter results like so it says undefined.
mounted(){
console.log(store.getters.getName);
},
It seems like the component is loading before the state is loaded. I am getting the user info using axios. I am really confused on how to solve this since I can not call the action to get the user data any sooner that I know of.
If in my getter method I do:
state.user
I get this:
{ "id": 1, "name": "Test" }
But when I try to get name I get undefined
Here is the store:
import axios from "axios/index";
const state = {
user: {},
};
const mutations = {
FETCH_USER(state,user){
state.user = user;
},
UPDATE_AVATAR(state,avatar){
state.user.avatar = avatar;
}
};
const getters = {
getName(state){
return state.user.name
},
avatar(state){
return state.user.avatar;
},
userSocialNetworks(state){
//return state.user.social_networks
},
schoolName(state){
return state.user.school
},
schoolAbout(state){
return state.user.school.about
},
schoolAddress(state){
return state.user.school.address
}
};
const actions = {
currentUser: ({commit}) => {
axios.get('/api/user').then(response => {
commit('FETCH_USER', response.data);
});
}
}
export default {
state,
getters,
actions,
mutations
}
{"user":{"user":{"name":"Test","email":"[email protected]","avatar":"http://www.gravatar.com/avatar/xxxx=300","city":null,"state":null,"zip":null,"address":null,"lat":null,"long":null,"role":"school","school":{"id":1,"about":null,"header":null,"name":"Test","user_id":1,"created_at":"2018-06-06 19:48:16","updated_at":"2018-06-06 19:48:16"},"following":[],"followers":[],"social_networks":[{"id":4,"user_id":1,"social_network_id":1,"network_url":"test.com/k","created_at":"2018-06-06 23:11:09","updated_at":"2018-06-06 23:15:19"},{"id":5,"user_id":1,"social_network_id":2,"network_url":"test.com/k","created_at":"2018-06-06 23:15:19","updated_at":"2018-06-06 23:15:19"},{"id":6,"user_id":1,"social_network_id":5,"network_url":"test.com/k","created_at":"2018-06-06 23:16:15","updated_at":"2018-06-06 23:16:15"}]}},"socialNetowrks":{"available_networks":[{"id":1,"network_name":"Facebook","created_at":null,"updated_at":null},{"id":2,"network_name":"Instagram","created_at":null,"updated_at":null},{"id":5,"network_name":"Twitter","created_at":null,"updated_at":null}]}}
You are facing two big issues here:
So make sure you declare all of your state correctly and you assign to objects instead of overwriting them
import assignDeep from 'assign-deep'; //Since you have nested structure you will need this
const state = {
user: {
name: '',
school: {
about: '',
address: '',
},
// Make sure all properties are defined
},
};
const mutations = {
FETCH_USER(state,user){
assignDeep(state.user, user);
},
UPDATE_AVATAR(state,avatar){
state.user.avatar = avatar;
}
};
First make use of the mapGetters
utility of vuex for easier usage
import { mapGetters } from 'vuex';
//... In component definition
computed: {
...mapGetters({name: 'getName'})
}
Since this is a vue computed property, your component will rerender when it gets defined and everything should display properly you just need to make sure you handle the case when it's empty and maybe display a loading screen until it is
For example
<template>
<div v-if="!name" class="loading"></div>
<div v-else>{{name}}</div>
<template>
You're also free to just wait for the property to update
Do not use it in the mounted hook as it will still be the default value there
Instead use a watcher or a computed property depending on your needs
watch: {
name: {
handler(name, oldName) {
if (name) {
//Do something
}
},
immediate: true
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With