I'm using Vue Resource to retrieve an images collection from a REST API. The request is sent in the created
hook of my Vue component.
The problem is, I'm trying to access the retrieved data in the mounted
hook, but the data isn't loaded.
I get this error in the console:
[Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'forEach' of undefined"
Here is my component:
<script>
export default {
data() {
return { imgs : '' };
},
created() {
// the full url is declare in my main.js
this.imgs = this.$resource('acf/v3/pages/4');
this.imgs.query().then((response) => {
console.log('success', response);
this.imgs = response.data.acf.gallery;
}, (response) => {
console.log('erreur', response);
});
},
mounted() {
// get the ref="image" in my dom template
let imgs = this.$refs.image;
imgs.forEach((img) => {
// I do some stuff with imgs
});
}
}
</script>
If I wrap a setTimeout
around the content of mounted
, everything works fine.
So, I don't understand how I can wait for my data to load before the mounted
hook is executed. Isn't this the role of the Vue lifecycle hooks?
Since the this.imgs.query()
call is async, your mounted
hook is being called before the then
handler is setting this.imgs
(which I'm assuming is being bound with v-for
to an element in your template with an attribute ref="image"
). So, even though the component has been mounted to the DOM, the $refs
have not been set up yet.
I would make a method to "do some stuff with imgs" and then call that method in a $nextTick
callback in the then
handler of the async call. The callback passed to $nextTick
will be "executed after the next DOM update cycle", meaning the $refs
will be set up at that point.
<script>
export default {
data() {
return { imgs: '' };
},
created() {
// the full url is declare in my main.js
this.imgs = this.$resource('acf/v3/pages/4');
this.imgs.query().then((response) => {
console.log('success', response);
this.imgs = response.data.acf.gallery;
this.$nextTick(() => this.doStuffWithImgs());
}, (response) => {
console.log('erreur', response);
});
},
methods: {
doStuffWithImgs() {
// get the ref="image" in my dom template
let imgs = this.$refs.image;
imgs.forEach((img) => {
// I do some stuff with imgs
});
}
}
}
</script>