Reputation: 51
I'm going crazy over this as I can't understand what I might be missing.. so I'm basically using vuex to store the state of the user. I've setup a route and use Axios to make a call to this route to retrieve some info from the user. I can see in vue dev tools that the state and everything are set I'm just having a real hard time accessing it. If I do the following console.log(this.$store.state.baseSettings)
in mounted then this shows the following:
Now I would have thought by adding .user onto that console.log I'd get exactly what I need but it shows an empty object.
I have also tried the following:
computed: {
user() {
return this.$store.state.baseSettings.user;
},
},
This works if I do {{ user }} in the template itself but if I try and access this.user
in computed, mounted, or any methods I also get an empty object. Is there any reason for this? Am I missing something simple/obvious here?
Any help would be greatly appreciated! Here's my full code:
app.js:
import Vue from 'vue';
import Vuetify from 'vuetify';
import router from '../../router';
import store from './store';
import {userComputed, settingsMethods} from './store/helpers';
import App from '../App.vue';
new Vue({
router,
store,
vuetify: new Vuetify(),
render: h => h(App),
computed: {
...userComputed,
},
methods: {
...settingsMethods,
},
mounted() {
return this.getAllSettings();
},
}).$mount('#app');
App.vue
<template>
<v-app>
{{ user }}
<v-main :class="!user ? 'background-img' : null">
<v-container fluid>
<nav-bar/>
<router-view/>
</v-container>
</v-main>
</v-app>
</template>
<script>
export default {
computed: {
user() {
// Works but only in above <template></template>
return this.$store.state.baseSettings.user;
},
},
mounted() {
// Returns object with user data (see screenshot).
console.log(this.$store.state.baseSettings);
// Empty object!
console.log(this.$store.state.baseSettings.user);
// Empty object
console.log(this.user)
}
}
</script>
baseSettings.js:
const state = {
user: {},
};
const getters = {
getUser: state => _.keys(state.user),
};
const actions = {
getAllSettings({ commit }) {
return axios.get('settings').then(baseSettings => {
commit('setUser', _.get(baseSettings, 'data.user', {}));
});
},
};
const mutations = {
setUser(state, user) {
state.user = user;
},
};
export default {
namespaced: true,
state,
getters,
actions,
mutations,
};
helpers.js:
import { mapActions, mapState } from 'vuex';
export const userComputed = {
...mapState('baseSettings', ['user']),
};
export const settingsMethods = {
...mapActions('baseSettings', ['getAllSettings']),
};
index.js
import Vue from 'vue';
import Vuex from 'vuex';
import baseSettings from '../modules/baseSettings';
Vue.use(Vuex);
const debug = process.env.NODE_ENV !== 'production';
export default new Vuex.Store({
modules: {
baseSettings,
},
strict: debug,
});
Thanks so much!
Upvotes: 1
Views: 725
Reputation: 453
This seems to be an unfulfilled promise problem.
You do both, retrieving the getAllSettings()
as well as trying to access the $store
independently of each other at the same lifecycle step. Therefore it is not guaranteed that the Axios call has already reported data and saved it to the store when you try to access it from there (resulting in the empty object at runtime).
However since the computed property reruns once the dependant variable changes, it will display correct in your component, as this happens after the mounted()
lifecycle step, when the Axios call has run through.
Upvotes: 1