Vue 2.0: passing async data to child component
I have a parent Vue component that passes data to its descendant via a prop, but the data is available asynchronously, so my child component is initialized to undefined values.
What can be done to prevent initialization until the data is available?
Parent:
var employees = new Vue({
el: '#employees',
data: { ... },
methods: {
fetch: function(model, args=null) {
let url = "/" + model + ".json"
console.log(url);
$.ajax({
url: url,
success: ((res) => {
console.log(res)
this[model] = res;
this.isLoading = false;
error: (() => {
this.isLoading = false;
}),
complete: (() => {
// $('.loading').hide();
this.isLoading = false;
})
})
},
mounted: function() {
this.fetch(...)
this.fetch(...)
this.fetch('appointments')
}
})
My extraction method is called multiple times.
Use Promise.all .
In the code below, I modified your method fetch
to return the promise from the ajax call. We can then collect these promises in an array and pass them in Promise.all
and do something when all the ajax calls are complete. In this case, set the property isLoading
so you can use v-if
for your child component.
var employees = new Vue({
el: '#employees',
data: { isLoading: true },
methods: {
fetch(model, args=null) {
let url = "/" + model + ".json"
const success = res => this[model] = res
const error = err => console.log(err)
return $.ajax({url, success, error})
}
},
mounted(){
let promises = []
promises.push(this.fetch('stuff'))
promises.push(this.fetch('otherstuff'))
promises.push(this.fetch('appointments'))
Promise.all(promises)
.then(() => this.isLoading = false)
.catch(err => console.log(err))
}
})
You can just use v-if
in the parent template:
<template v-if="everthingIsReady">
<child-item :data="data"></child-item>
</template>
The child item will not be created until everythingIsReady
it is set to true
, and you can install it immediately after completing all your calls.