I want to create a chart by add labels and data from an API and update this one.
I create a method addData() in chartsponent.ts that looks in this way:
addData(chart, labels_builds,labels_data){
chart.data.labels.push(labels_builds);
chart.data.datasets.data.forEach(dataset => {
dataset.data.push(labels_data);
});
chart.update();
}
This will be call here:
getMisraLintChart(projectVariantId: number,filterType : string, filterValue: string): void {
this.chartService.getMisraLintChart(projectVariantId, filterType, filterValue)
.subscribe(pageChart =>{
this.chartMisraLint = pageChart
this.addData(this.myChart,pageChart.build,pageChart.data);
})
}
In ngOnInit() i have this code:
ngOnInit() {
this.getFilters();
var ctx = document.getElementById("myChart");
this.myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: '# of Total Messages',
data: [],
backgroundColor:'#ffe4c9',
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
}
,
scaleLabel: {
display: true,
labelString: 'Total Messages'
}
}]
,
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Builds'
}
}]
}
}
});
I get the error :ERROR TypeError: Cannot read property 'forEach' of undefined.
If anyone could push me in the right direction, it would be greatly appreciated!
I want to create a chart by add labels and data from an API and update this one.
I create a method addData() in charts.ponent.ts that looks in this way:
addData(chart, labels_builds,labels_data){
chart.data.labels.push(labels_builds);
chart.data.datasets.data.forEach(dataset => {
dataset.data.push(labels_data);
});
chart.update();
}
This will be call here:
getMisraLintChart(projectVariantId: number,filterType : string, filterValue: string): void {
this.chartService.getMisraLintChart(projectVariantId, filterType, filterValue)
.subscribe(pageChart =>{
this.chartMisraLint = pageChart
this.addData(this.myChart,pageChart.build,pageChart.data);
})
}
In ngOnInit() i have this code:
ngOnInit() {
this.getFilters();
var ctx = document.getElementById("myChart");
this.myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: '# of Total Messages',
data: [],
backgroundColor:'#ffe4c9',
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
}
,
scaleLabel: {
display: true,
labelString: 'Total Messages'
}
}]
,
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Builds'
}
}]
}
}
});
I get the error :ERROR TypeError: Cannot read property 'forEach' of undefined.
If anyone could push me in the right direction, it would be greatly appreciated!
Share Improve this question asked Nov 21, 2018 at 13:26 MadalinaMadalina 611 gold badge4 silver badges12 bronze badges 5-
chart.data.datasets.data.forEach()
data seems to be undefined I guess – Marv Commented Nov 21, 2018 at 13:29 - Do you want a chart based on API data, and update chart if data changes? – Maihan Nijat Commented Nov 21, 2018 at 13:30
-
Should it be
chart.data.datasets.forEach
? Because you have named the parameter asdataset
– adiga Commented Nov 21, 2018 at 13:30 - Yes. I want a chart based on API data and it should be updated based on the data it receives. – Madalina Commented Nov 21, 2018 at 13:34
- I put chart.data.datasets.forEach and i don't see the error anymore but my chart doesn't work. – Madalina Commented Nov 21, 2018 at 13:41
2 Answers
Reset to default 1Technically you receive this error because you never initialized this.myChart.data.datasets.data before looping over it. You've only typed it. You could fix that by setting a default array, like so:
ngOnInit() {
this.getFilters();
var ctx = document.getElementById("myChart");
this.myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [] = [] // might as well,
datasets: [{
label: '# of Total Messages',
data: [] = [], // <== note this part, the initialization
backgroundColor:'#ffe4c9',
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
}
,
scaleLabel: {
display: true,
labelString: 'Total Messages'
}
}]
,
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Builds'
}
}]
}
}
});
That being said, I am pretty sure this will not resolve your functional goal. I am pretty sure you don't want to add result elements from the server call based on the items already there; but just want to add them all. You're frankly looping the wrong data. So you'll also have to change the addData method. Like this:
addData(chart,
labels_builds = [], // See ment below
labels_data = [] // added this as an alternative null check for your server data.
){
chart.data.labels = [
...chart.data.labels, // Check the ES6 spread operator, you'll like it.
...labels_builds // In essence in this case it means "every element of"
];
chart.data.datasets.data = [
...chart.data.datasets.data,
...labels_data
];
chart.update();
}
Try This:
updateChart() {
//first set datasets length 0
this.chart.data.datasets.length = 0;
//call update method
this.chart.update();
const color = Chart.helpers.color;
//define your data here
let data1 = {
labels: ['1 Jan', '2 Jan', '3 Jan', '4 Jan', '5 Jan', '6 Jan', '7 Jan'],
datasets: [
{
fill: false,
borderWidth: 3,
backgroundColor: color(this.layoutConfigService.getConfig('colors.state.brand')).alpha(0.6).rgbString(),
borderColor: this.layoutConfigService.getConfig('colors.state.primary'),
label: 'Value1',
pointStyle: 'line',
pointHoverRadius: 4,
pointHoverBorderWidth: 12,
pointBackgroundColor: Chart.helpers.color('#000000').alpha(0).rgbString(),
pointBorderColor: Chart.helpers.color('#000000').alpha(0).rgbString(),
pointHoverBackgroundColor: this.layoutConfigService.getConfig('colors.state.primary'),
pointHoverBorderColor: Chart.helpers.color('#000000').alpha(0.1).rgbString(),
data: [this.getNo(), this.getNo(), this.getNo(), this.getNo(), this.getNo(),this.getNo(),this.getNo()]
}
]
};
//asign data1 to chart data
this.chart.data = data1;
//again update chart
this.chart.update();
}
getNo() {
return Math.floor((Math.random() * 100 ) + 1);
}
This worked for me...!