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
loadedset to false in your root vue instance and pass it as a propchange the
loadedtotruein the success callback of the promise returned by yourths.$http.get()requestsetup a watcher in your
chartcomponent watching over thisloadedpropinvoke the
drawChartmethod when theloadedpropchanges totrue`
