angular & "ReferenceError: google is not defined"

2,402 views
Skip to first unread message

Andrea Buzzi

unread,
Sep 30, 2020, 9:36:10 AM9/30/20
to Google Visualization API

Hello,
due to some missing feature on  "FERNman / angular-google-charts" wrapper (like: role "style"/"annotation") I'm trying to feed the classic "google.charts.load" into a fresh test-ui angular project (v10).

So far I've put in app.component.html:

<html>
  <head>
   <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  </head>

  <body>
   <div id="donutchart" style="width: 900px; height: 500px; border:solid 1px black"></div>
  </body>
</html>

while app.component.ts I've the following:

import { Component } from '@angular/core';

declare var google: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'test-ui';

  drawChart=function() {
  var data = google.visualization.arrayToDataTable([['Task', 'Hours per Day'], ['Work', 11], ['Eat', 2], ['Commute', 2], ['Watch TV', 2], ['Sleep', 7] ]);
  var options = { title: 'My Daily Activities', pieHole: 0.4 };
  var chart = new   google.visualization.PieChart(document.getElementById('donutchart'));
  chart.draw(data, options);
}

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

}


Unfortunately this generate a "ERROR ReferenceError: google is not defined"...

Any tip to make this sample graph working in a angular environment ?

Thx in advance for any suggestion/hint/example!

Andrea


Daniel LaLiberte

unread,
Sep 30, 2020, 10:58:29 AM9/30/20
to Google Visualization API
Hi Andrea,

That kind of error, "google is not defined", means that at the time you use the google symbol, the loader has not finished loading.  I suspect the problem might be that ngOnInit is called before the component html has been defined and/or used, so the loader has not necessarily finished loading.   

Since your app-component html really looks more like a full page, including html head and body, maybe you should separate out the chart drawing parts into a chart-component.   

--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-visualizati...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-visualization-api/435f4d45-d323-476c-8821-fc7c8c57dda5n%40googlegroups.com.


--

Andrea Buzzi

unread,
Sep 30, 2020, 1:06:05 PM9/30/20
to Google Visualization API
Hello Daniel,

I tried to move load from ngOninit() to ngAfterViewInit() but still getting same error, "google is not defined"

ngOnInit() {
}

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

I found a document ( https://anthonygiretti.com/2017/10/12/using-google-charts-in-angular-4-project-part-1/ ) that suggest to create first a class for a generic GoogleChartsBaseService then instantiate a PieChartConfig model where data can be passed along the different components.
While I'm sure that is the best way to approach this.... its logic is a bit too deep for me (for the time beeing at least)... so I'm really looking for a simple working snippet that I can load then adapt to my project....

Should you have any available.... :)

Thx,
Andrea

Daniel LaLiberte

unread,
Sep 30, 2020, 1:34:48 PM9/30/20
to Google Visualization API
That article you reference appears to be doing the kind of things I imagine are necessary to load the loader and then call google.charts.load.  At the end of the second part is a link to the source, which may help you put together all the necessary parts.

Andrea Buzzi

unread,
Sep 30, 2020, 4:08:07 PM9/30/20
to Google Visualization API
Hello Daniel,

k, I followed:

 npm install

then because of "ERROR in DataTableModule is not an NgModule" I followed following tip:

 Just replace in app.module.ts:
 import { DataTableModule } from 'angular-4-data-table';
 with
 import { DataTableModule } from 'angular-4-data-table/src/index';

and now the Google Charts demo is working so I can analyze it.

Thank you so much for the appreciated time you took on providing guidance.

THx,
Andrea

Andrea Buzzi

unread,
Oct 3, 2020, 8:45:10 AM10/3/20
to Google Visualization API
Hello,

finally I understood the issue I was facing...  I erroneously forgot that in angular application there is still a index.html (my bad).
So to have a example google graph (using old way) in a simple way just follow these instructions:

ng new test-ui

in 'src/index.html' add before </head>:
 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

replace content of 'src/app/app.component.html' with:
  <div id="donutchart" style="width: 900px; height: 500px; border:solid 1px black;"></div>

replace 'src/app/app.component.ts' with:

import { Component } from '@angular/core';

declare var google: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'test-ui';

  drawChart=function() {
  var data = google.visualization.arrayToDataTable([['Task', 'Hours per Day'], ['Work', 11], ['Eat', 2], ['Commute', 2], ['Watch TV', 2], ['Sleep', 7] ]);
  var options = { title: 'My Daily Activities', pieHole: 0.4 };
  var chart = new   google.visualization.PieChart(document.getElementById('donutchart'));
  chart.draw(data, options);
}

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

}

Do "ng serve" and enjoy the graph displayed.

Thank you,
A.

Andrea Buzzi

unread,
Oct 3, 2020, 9:30:51 AM10/3/20
to Google Visualization API
Hello,

one further note... if setOnLoadCallback call just drawChart then class variable (this.content) are not accessible:

drawChart() {
var srcdata = this.content["data"];   <= this element is not accessible
var data = google.visualization.arrayToDataTable(srcdata);   <= this is working fine
[...]
}

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

if instead in setOnLoadCallback we call drawChart() then the google.visualization is not accessible:

drawChart() {
var srcdata = this.content["data"];   <= this element is accessible
var data = google.visualization.arrayToDataTable(srcdata);   <= this now fails
[...]
}

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

I workaround that using:

ngOnInit() {
   google.charts.load('current', {'packages':['corechart']});
   setTimeout(() => {
     this.drawChart();
   }, 500);
}

The setTimeout allows too call drawChart() with access to the class variable (this.content) and also give enough time to fully load the google.visualization command.

Hope it helps.

Thx,
A.
Reply all
Reply to author
Forward
0 new messages