Randomly get: "TypeError: google.visualization.DataTable is not a constructor"

google-visualization, javascript

Solution

the documentation is pretty stale at this point...

don't recommend using more than one `setOnLoadCallback` statement

actually, you can place the `callback` directly in the `load` statement

and you can depend on the `callback` to know when the page is ready

no need for --> `$(document).ready`

try following setup, load google before anything else...

google.charts.load('current', {
  callback: drawCharts,
  packages: ['corechart']
});

function drawCharts() {
  if (window.location.href == 'XXXXXController') {
      $.ajax({
          type: "POST",
          url: "/draw_dual_lineChart",
          data: "someParameters",
          dataType:"json"
      }).done(function (jsonData) {
          // Create our data table out of JSON data loaded from server.
          var data_chart = new google.visualization.DataTable(jsonData[0]['data']);
          // Set chart's options
          var options = jsonData[1]['options'];
          // Instantiate and draw the chart
          var chart = new google.visualization.LineChart(document.getElementById('dual_chart_revenues_expenses'));
          chart.draw(data_chart, options);
      });

      $.ajax({
          type: "POST",
          url: "/draw_single_lineChart",
          data: "someParameters",
          dataType:"json"
      }).done(function (jsonData) {
          // Create our data table out of JSON data loaded from server.
          var data_chart = new google.visualization.DataTable(jsonData[0]['data']);
          // Set chart's options
          var options = jsonData[1]['options'];
          // Instantiate and draw the chart
          var chart = new google.visualization.LineChart(document.getElementById('single_chart_affluence'));
          chart.draw(data_chart, options);
      });
    }
  }
}

Problem

I'm drawing several charts on one of my webpage, however I randomly get the following error in the console: ``` TypeError: google.visualization.DataTable is not a constructor ``` I've tried to narrow down the issue by displaying one chart only but I still get the error message and no charts are drawn, about 50% of the time. When I don't get the errors the chart(s) is drawn properly. I've read multiple forums and this documentation but I can't see what is wrong. I have basically the same code as the mentioned documentation, except that my functions are declared BEFORE the `setOnLoadCallback`, otherwise they get `undefined`. Some of my (simplified) code: MyPage.php : ``` <!DOCTYPE html> <html> <head> // loading CSS </head> <body> <p>My page content...</p> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script> <script src="https://www.gstatic.com/charts/loader.js"></script> <script src="/js/home.js" type="text/javascript"></script> // loading more scripts (moment.js, query.countdown.js, bootstrap.js...) </body> </html> ``` In home.js : ``` $(document).ready(function(){ if (window.location.href == 'XXXXXController') { // This chart draws a dual axis chart showing revenues and expenses function drawRevenuesExpenses() { var jsonData = $.ajax({ type: "POST", url: "/draw_dual_lineChart", data: "someParameters", dataType:"json" }).done(function (jsonData) { // Create our data table out of JSON data loaded from server. var data_chart = new google.visualization.DataTable(jsonData[0]['data']); // Set chart's options var options = jsonData[1]['options']; // Instantiate and draw the chart var chart = new google.visualization.LineChart(document.getElementById('dual_chart_revenues_expenses')); chart.draw(data_chart, options); }); } // This chart draws the resort's affluence (number of tourists per day) function drawAffluence() { var jsonData = $.ajax({ type: "POST", url: "/draw_single_lineChart", data: "someParameters", dataType:"json" }).done(function (jsonData) { // Create our data table out of JSON data loaded from server. var data_chart = new google.visualization.DataTable(jsonData[0]['data']); // Set chart's options var options = jsonData[1]['options']; // Instantiate and draw the chart var chart = new google.visualization.LineChart(document.getElementById('single_chart_affluence')); chart.draw(data_chart, options); }); } google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawRevenuesExpenses); //google.charts.setOnLoadCallback(drawAffluence); } } ```

Original source