Felix Eklöf
Felix Eklöf

Reputation: 3720

Do something after fetch and mounted complete

I have a simple nuxt.js component like the one below.

Chart is a component that has a method which will receive the data that is fetched in fetch().

If I simply call that method after await fetch('...') I get an error when it's rendered on client-side since the Chart component has not yet been mounted. How could I go about to do something after fetch AND mounted?

And I can't do it in mounted() because then I can't be sure that the fetch is complete.

<template>
    <div>
        <!--Custom component-->
        <Chart ref="chart"/> 
    </div>
</template>

<script>
    export default {
        data(){
            return {
                chartData: []
            }
        },
        async fetch() {
            this.chartData = await fetch('https://api.mocki.io/v1/b1e7c87c').then(res =>
                res.json()
            )
            this.$refs.chart.insertSeries(this.chartData) // doesn't work because Chart is not mounted yet.
        },
    }
</script>

Upvotes: 1

Views: 2343

Answers (1)

Dan
Dan

Reputation: 63059

The preferred way of handling this situation would be to use a prop so that <Chart> can handle the data itself, and watch the prop in the child.

Parent

<Chart :chart-data="chartData" /> 

Chart

export default {
  props: ['chartData'],
  watch: {
    chartData(newValue) {
      if(newValue.length) {
        this.insertSeries(newValue);
      }
    }
  },
  ...
}

Variation: You could use v-if instead of a watch:

Parent

<Chart v-if="chartData.length" :chart-data="chartData" /> 

Chart

export default {
  props: ['chartData'],
  created() {
    this.insertSeries(this.chartData);  // `chartData` is guaranteed to exist
  }
  ...
}

Note: There is a slight difference that can emerge between these two options. Imagine you wanted a loading animation while chart data was loading.

With the first option, since the component is shown immediately, the loading functionality would have to be put in the child. In the second option, it would be put in the parent (in a v-else).

Upvotes: 1

Related Questions