3

Currently I have a component using vue and c3. The c3 chart renders immediately, however I am still grabbing the data via ajax. How do I delay the rendering of the component? OR once the data is fetched THEN display the chart.

My code is pretty straighforward.

<my-chart :chartdata="chart.data"></my-chart> etc.

Note: If I enter static data - it renders perfectly.

JSFIDDLE https://jsfiddle.net/1o4kqjwd/3/

KingKongFrog
  • 13,946
  • 21
  • 75
  • 124
  • Presuming the ajax call returns a promise, initialize c3 in a `then`. – Bert May 02 '17 at 22:57
  • How do I initialize it after the ajax call IF the logic to generate it is in the component? – KingKongFrog May 02 '17 at 22:58
  • Do the ajax call the a lifecycle event like `mounted` or `created`. If this is the same thing as your next to last question, in `mounted`, make the ajax and initialize c3 in the callback. – Bert May 02 '17 at 23:01
  • Can't you just do ``? – thanksd May 03 '17 at 00:43
  • @thanksd good idea. However if I want to pulse the API and update the chart that wouldn't work. – KingKongFrog May 03 '17 at 01:43
  • @KingKongFrog would it not? Could you show how the ajax call is setting `chart.data`? – thanksd May 03 '17 at 01:48
  • @thanksd I've added a fiddle above. It sends in default data and then calls an API. Bear in mind the data is crazy for this example but just trying to render the graph with whatever data. – KingKongFrog May 03 '17 at 02:01
  • @BertEvans Added a fiddle, would love your input. – KingKongFrog May 03 '17 at 02:01
  • Do you want the initial data displayed? Then updated with the returned data? Or just displayed after the ajax is returned? https://jsfiddle.net/1o4kqjwd/6/ – Bert May 03 '17 at 02:16
  • @KingKongFrog. 1) You weren't assigning `self` in the ajax callback in your fiddle. 2) I think it might be the amount of categories in the retrieved data was breaking the chart. I edited your fiddle to assign random values to the categories when the ajax call returns and the chart is updating 3) I also added a watcher to `mydata` in the `my-chart` component to rerender the chart when the data changes https://jsfiddle.net/1o4kqjwd/5/ – thanksd May 03 '17 at 02:16
  • @thanksd If I could have our baby, I would have 10. This worked flawlessly. Thank you for your time. Feel free to add a solution so I could accept it. – KingKongFrog May 03 '17 at 02:39
  • @KingKongFrog glad to help! – thanksd May 03 '17 at 03:27

1 Answers1

4

First, add a v-if directive to the <my-chart> tag to only render it when the data (mydata, in your fiddle) is loaded:

<my-chart :chartdata="mydata" v-if="mydata"></my-chart>

Second, in the component definition for my-chart, you need to add a watcher to mydata to call the render method (drawChart(), in your fiddle) whenever mydata changes:

watch: {
  mydata() {
    this.drawChart();
  }
},

Finally, you can put the ajax call in its own method on the parent Vue definition. This way, you can call it in the mounted() life-cycle hook and then subsequently from anywhere within that instance's scope:

methods: {
  fetchData() {
    var self = this;  

    this.$http.get('yoururl').then(function(response) {
      let chartData = response.data;

      // do any formatting to chartData here

      self.data = chartData;
    })
  }
}
thanksd
  • 54,176
  • 22
  • 157
  • 150
  • I think the name of the property is watch, not watchers: `watch: { mydata: () => {...}}` – lukas_o Nov 17 '17 at 11:24
  • You're right that was a typo. Thanks! And you maybe weren't suggesting this, but just fyi that you shouldn't use an arrow function in this case because you'll lose the context of `this`. See https://stackoverflow.com/questions/43929650/vuejs-why-is-this-undefined/43929651#43929651 – thanksd Nov 17 '17 at 12:01