I think It's because Vue doesn't wait for response from server (AJAX fetching data), so at the one moment countries object is empty.
What you could try is wrap your template content into div and set v-if="countries" attribute.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
My data works fine and populates the template, however I get warning: vue.js:2215 TypeError: Cannot read property 'short_name' of undefined
This seems to result from my computed variable countryName defined as this.countries[this.selected].short_name. I've tried declaring data: and props: short_name and inside of the country object; nothing I try solves the warning.
<script>
Vue.config.devtools = true;
Vue.config.debug = true;
Vue.component('mark-country-selector', {
template: '#mark-country-template',
data: function() {
return {
selected: 'US',
countries: {}
};
},
computed: {
: function() {
return this.countries[this.selected].short_name
}
},
created: function() {
this.fetchCountries();
},
methods: {
fetchCountries: function() {
this.$http.get('api/countries', function(countries) {
this.countries = countries;
}.bind(this));
}
}
});
new Vue({
el: '#mark-country'
});
</script>
Console warnings:
vue.js:2212 [Vue warn]: Error when evaluating expression "function () {
return this.countries[this.selected].short_name
}". exports.warn @ vue.js:2212Watcher.get @ vue.js:6030Watcher.evaluate @ vue.js:6214computedGetter @ vue.js:8826(anonymous function) @ VM346954:3Watcher.get @ vue.js:6024Watcher @ vue.js:5992Directive._bind @ vue.js:9556linkAndCapture @ vue.js:2507compositeLinkFn @ vue.js:2485exports._compile @ vue.js:9267exports.$mount @ vue.js:10456exports._init @ vue.js:8443MarkCountrySelector @ VM346952:2build @ vue.js:5723mountComponent @ vue.js:5643(anonymous function) @ vue.js:5608(anonymous function) @ vue.js:5623cb @ vue.js:542exports._resolveComponent @ vue.js:9858resolveComponent @ vue.js:5625setComponent @ vue.js:5607bind @ vue.js:5564Directive._bind @ vue.js:9529linkAndCapture @ vue.js:2507compositeLinkFn @ vue.js:2485exports._compile @ vue.js:9268exports.$mount @ vue.js:10456exports._init @ vue.js:8443Vue @ vue.js:80(anonymous function) @ aircraft:864
vue.js:2215 TypeError: Cannot read property 'short_name' of undefined
at MarkCountrySelector.countryName (aircraft:849)
at Watcher.get (vue.js:6024)
at Watcher.evaluate (vue.js:6214)
at MarkCountrySelector.computedGetter [as countryName] (vue.js:8826)
at MarkCountrySelector.eval (eval at exports.compileGetter (vue.js:6876), <anonymous>:3:9)
at Watcher.get (vue.js:6024)
at new Watcher (vue.js:5992)
at Directive._bind (vue.js:9556)
at linkAndCapture (vue.js:2507)
at compositeLinkFn (vue.js:2485)
@bedakb That wouldn't work since countries is already defined as an empty object in data v-if would still return true.
@stwilson if 'us' is always the default for selected you could add it to the countries object in data.
data: function() {
return {
selected: 'US',
countries: { 'US' : 'United States' }
};
},
That way it will always have that default to show before your countries have been fetched.
Alternatively you could go with
if(typeof this.countries[this.selected] !== 'undefined'){
return this.countries[this.selected].short_name;
}
Please or to participate in this conversation.