Reputation: 989
I am trying to load a JSON file of content into my vuejs app and accessing it in my components. I am able to load the json into the vuex store by creating an API:
import Vue from 'vue';
const Http = new Vue();
export function getData() {
return Http.$http.get('./app/assets/content/en_uk.json')
.then(response => Promise.resolve(response.data))
.catch(error => Promise.reject(error));
}
and an action
export const getSiteContent = ({commit}) => {
api.getData().then(data => {
commit('siteContent', data);
});
};
I run getSiteContent on created function of the main vue instance
export default new Vue({
el: '#root',
store,
router,
created() {
getSiteContent(store);
},
render: h => h('router-view')
});
using the vue debug tool in chrome i can see the store
export const state = {
isSearching: false,
searchQuery: '',
siteData: {},
filteredComponents: [],
hasResults: false,
activeComponent: null
};
gets updated with the siteData.
This is part of the json:
{
"global": {
"project_name": {
"text": "Project title"
},
"search": {
"form_placeholder": {
"text": "Search..."
},
"no_results": {
"text": "Sorry no results for '{0}' was found"
},
"search_text": {
"text": "You are searching for '{0}' and there are {1} found"
}
}
}
}
When I try and access
computed: {
...mapGetters(['siteData']),
mumbo () {
return this.siteData.global.project_name;
}
}
in my component like {{mumbo}}
I get cannot read property of project_name of undefined.
I feel like this is a time issue as it doesn't fall over when I set it to return siteData.global
I'm not sure if I am doing something wrong or I am missing a connection to get this to work.
Upvotes: 2
Views: 8059
Reputation: 4020
As you guessed the problem here is that Vue is trying to access the contents of siteData
for that computed property while the data is still loading. Although siteData
is a valid object initially, trying to access siteData.global.project_name
fails because siteData
has no field global
when the data hasn't loaded yet. To prevent the error, you will have to include a check like this:
mumbo () {
return this.siteData.global ? this.siteData.global.project_name : 'Loading...';
}
To illustrate the solution, here's a simple JSFiddle based on your code.
Upvotes: 1