Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue 2.0: Passing asynchronous data to child component

I have a parent Vue component that passes data to its child through a prop, but the data is available asynchronously and so my child component initializes with undefined values.

What can I do 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 fetch method is called multiple times.

like image 856
Jeremy Thomas Avatar asked Jul 12 '17 13:07

Jeremy Thomas


Video Answer


2 Answers

You can just use v-if in your parent template:

<template v-if="everthingIsReady">
    <child-item :data="data"></child-item>
</template>

Child Item won't be created until everythingIsReady is set to true and you can set it right after all your calls complete.

like image 188
Krzysztof Atłasik Avatar answered Sep 23 '22 03:09

Krzysztof Atłasik


Use Promise.all.

In the code below, I modified your fetch method to return the promise from the ajax call. We can then collect those promises in an array and pass them to Promise.all and do something when all of the ajax calls have completed. In this case, set the isLoading property so that you can use v-if on 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))
  }
})
like image 23
Bert Avatar answered Sep 22 '22 03:09

Bert