Reputation: 481
I am working on a app in vue right now that has an object with a few nested objects. Right now in my school object in the user object I can display the school object, but when I try to get the name attribute of the school object I get undefined for the name attribute when it has a value.
This is my state of the application:
{
"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,
"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
}]
}
}
Here are my getters
const getters = {
name(state){
return state.user.school.name
}
};
const mutations = {
FETCH_USER(state,user){
state.user = user;
}
};
const actions = {
getUser: ({commit}) => {
axios.get('/user').then(response => {
commit('FETCH_USER', response.data);
});
}
}
When I just return the school object I get the object
{
"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"
}
But when I return state.user.school.name I get undefined. Does Vuex not work if you have nested objects?
Upvotes: 9
Views: 12098
Reputation: 53
Seems like a Vue reactivity issue, as described in VueJS and Vuex documentations :
https://v2.vuejs.org/v2/guide/reactivity.html
https://vuex.vuejs.org/guide/mutations.html#mutations-follow-vue-s-reactivity-rules
Vue cannot detect property addition or deletion. You can either declare all your properties with empty values from the start, or use Vue.set(), or replace your state object with a fresh new one using Object.assign() or ES6 spread operator :
state.user = { ...user }
Upvotes: 4
Reputation: 394
I have exactly the same problem, indeed the console shows the object is populated, but accessing its child property returns undefined. My code has the same structure (fetching data with axios in an action, then commiting mutation). I have a simple getter:
getters: {
users: state => state.users,
},
From a component, I perform:
console.log(this.$store.getters.users);
console.log(this.$store.getters.users.preprod);
and believe it or not, the output is:
> {…}
__ob__: Object { value: {…}, dep: {…}, vmCount: 0 }
preprod: Array(4) [ {…}, {…}, {…}, … ]
<prototype>: Object { … }
> undefined
The only clue I have for the moment is that these values are gotten from a script called cjs.js
located at wbepack-internal:///./node_modules/cache-loader/dist/cjs.js
. So may this be an issue with webpack caching?
Upvotes: 1
Reputation: 71
I ran in to this problem and resolved it by defining the nested object/property needed when declaring state, even if the value is empty or null to start.
So the minimum you would need to stop getting undefined for state.user.school.name would be.
const state = {
user: {
school: {
name: ''
}
}
}
Obviously you will want to continue to expand that for other nested properties you need defined.
Upvotes: 7