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.

+3


source to share


2 answers


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))
  }
})

      

+2


source


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.

+1


source







All Articles