This is how json response looks like [[61,57,34],[1,1,3]]
I want to use the first array for labels and the second for data.
If I set labels and data
inside app
manually it works though.
eg
labels: ["q", "w", "e"]
data: [1, 5, 10]
Vue.component('chart', { props: ['labels', 'data', 'type'], template: ` <canvas style="width: 512px; height: 256px"></canvas> `, mounted: function () { new Chart(this.$el, { type: this.type, data: { labels: this.labels, datasets: [{ label: '# of Votes', data: this.data, borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }) } }); new Vue({ el: '#app', data: { message: "test", labels: [], data: [] }, methods: { fetchData: function() { this.$http.get('/admin/fetch_data').then(res => { this.labels = res.body[0]; this.data = res.body[1]; }) } }, beforeMount() { this.fetchData() } });
component on page
<div id="app"> {{message}} <chart :labels="labels" :data="data" type="bar"></chart> </div>
The data seems to be loaded but there’re no chart bars on page.
Advertisement
Answer
The problem is your data is not yet fetched as you are performing an async task to fetch your data. By that time the component’s mounted hook is called with empty props as the data you are passing as props is not yet loaded.
So do it like this:
Vue.component('chart', { props: ['labels', 'data', 'type' 'loaded'], template: ` <canvas style="width: 512px; height: 256px"></canvas> `, watch:{ loaded(isLoaded){ if(isLoaded){ this.drawChart(); } } }, methods:{ drawChart: function () { new Chart(this.$el, { type: this.type, data: { labels: this.labels, datasets: [{ label: '# of Votes', data: this.data, borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero:true } }] } } }) } } }); new Vue({ el: '#app', data: { message: "test", labels: [], data: [], loaded: false }, methods: { fetchData: function() { this.$http.get('/admin/fetch_data').then(res => { this.labels = res.body[0]; this.data = res.body[1]; this.loaded = true; }) } }, created() { this.fetchData() } });
html
<div id="app"> {{message}} <chart :labels="labels" :data="data" :loaded="loaded" type="bar"></chart> </div>
add a property
loaded
set to false in your root vue instance and pass it as a propchange the
loaded
totrue
in the success callback of the promise returned by yourths.$http.get()
requestsetup a watcher in your
chart
component watching over thisloaded
propinvoke the
drawChart
method when theloaded
propchanges to
true`