Angular: loop it's returning me an undefined value

129 views Asked by At

I'm trying to use Google Charts to draw a chat based on my array of objects.

I get the array, map the values to make a loop in the objects, and insert each value in the chart. But it's not working because the value that's returning for me it's undefined.

I don't know what to do. When I do that on ngOnInit() the values it returns for me normally, bus when I put this logic in some function, is not work =(

component.ts

   declare var google: any;

   @Component({selector, template...})

   export class AppComponent implements OnInit {

    tableContent!: ProgressTableDatas[];

    constructor(private dropdownService: DropdownService) { }

    ngOnInit(): void {
     this.tableContent = this.dropdownService.getProgressTableDatas();

     let datas = this.tableContent.map(data => data);

     for (let i = 0; i <= datas.length; i++) {
         console.log(datas[i].region, datas[i].budget, datas[i].closed);

         //Here the values it returns for me normally, like that
         // Region1 0.00 0.00
         // Region2 0.00 0.00...

     }

     google.charts.load('current', { packages: ['corechart'] });
     google.charts.setOnLoadCallback();
     google.charts.setOnLoadCallback(this.drawColumnChart);
   }

    // Here I get this error 'Cannot read properties of undefined (reading 'region').'

    drawColumnChart() {
     let datas = this.tableContent.map(data => data);

     for (let i = 1; i <= datas.length; i++) {
       var graphic = google.visualization.arrayToDataTable([
         ['Region', 'Budget', 'Closed'],
         [datas[i].region, datas[i].budget, datas[i].closed]
       ]);
     }

     var chart = new google.visualization.ColumnChart(document.getElementById('progressGraphic'));

     chart.draw(graphic);
    }

   }

dropdown.service

getProgressTableDatas() {
    return[
      {
        "region": "Region1",
        "budget": "0.00",
        "closed": "0.00"
      },
      {
        "region": "Region2",
        "budget": "0.00",
        "closed": "0.00"
      },      {
        "region": "Region3",
        "budget": "0.00",
        "closed": "0.00"
      },
      {
        "region": "Region4",
        "budget": "0.00",
        "closed": "0.00"
      },
      {
        "region": "Region5",
        "budget": "0.00",
        "closed": "0.00"
      },
      {
        "region": "Region6",
        "budget": "0.00",
        "closed": "0.00"
      },
    ]
  }
1

There are 1 answers

2
WhiteHat On

arrays in javascript have a zero-based index,
meaning the first index in the array is 0.
and the last index is the length - 1.
if an array has 6 elements, the last index is 5.

here, you're starting at 1 and ending at 6.

 for (let i = 1; i <= datas.length; i++) {

in this case datas[6] is undefined...

you should be starting at 0 and ending at 5.

 for (let i = 0; i < datas.length; i++) {

*** also ***

you only need to call setOnLoadCallback once...

 google.charts.setOnLoadCallback();  // <-- remove this
 google.charts.setOnLoadCallback(this.drawColumnChart);

*** EDIT ***

from the comment, it sounds like you losing context or reference to this
Cannot read properties of undefined (reading 'tableContent')

as such, try drawing the chart inside ngOnInit, as follows.
note: the values for each series should be a number 0, not a string "0.00"

ngOnInit(): void {
  this.tableContent = this.dropdownService.getProgressTableDatas();

  let datas = this.tableContent.map(data => {
    return [data.region, parseFloat(data.budget), parseFloat(data.closed)];
  });

  google.charts.load('current', {
    packages: ['corechart']
  }).then(function () {
    var graphic = google.visualization.arrayToDataTable(datas);

    var chart = new google.visualization.ColumnChart(document.getElementById('progressGraphic'));

    chart.draw(graphic);
  });
}