Reputation: 8626
I am trying to create a pie chart using google charts. But I am getting the following error
Uncaught TypeError: Cannot read property 'arrayToDataTable' of undefined
at drawContactsStatisticsChart
What I am doing wrong ?
Here is my code
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script language="JavaScript" type="text/javascript">
(function($) {
// Load the Visualization API and the corechart package.
google.charts.load("current", {packages:["corechart"]});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawContactsStatisticsChart);
var contatatsStatisticsData;
var contactsStatisticsChart;
var emailCampaignId = 1;
var stepId = 0;
var queryString = "emailCampaignId=" + emailCampaignId + "&stepId=" + stepId ;
var getEmailCampaignUrl = "/mailgun/getAggregatedStats.htm";
function drawContactsStatisticsChart(totalDelivered, totalBounced, totalOpened, totalClicked, totalUnsubscribed, totalComplained) {
contatatsStatisticsData = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['DELIVERED = ' + totalDelivered, totalDelivered],
['BOUNCED = ' + totalBounced, totalBounced],
['OPENED = ' + totalOpened, totalOpened],
['CLICKED = ' + totalClicked, totalClicked],
['UNSUBSCRIBED = ' + totalUnsubscribed, totalUnsubscribed],
['COMPLAINED = ' + totalComplained , totalComplained]
]);
// Set chart options
var options = {
title: 'My Campaign Statistics',
is3D: true,
};
// Instantiate and draw our chart, passing in some options.
contactsStatisticsChart = new google.visualization.PieChart(document.getElementById('pieChart_3d'));
google.visualization.events.addListener(contactsStatisticsChart, 'select', selectHandler);
contactsStatisticsChart.draw(contatatsStatisticsData, options);
}
function showEmailCampaignStatistics(response) {
var totalDelivered = response.totalDelivered;
var totalBounced = response.totalBounced;
var totalOpened = response.totalOpened;
var totalClicked = response.totalClicked;
var totalUnsubscribed = response.totalUnsubscribed;
var totalComplained = response.totalComplained;
drawContactsStatisticsChart(totalDelivered, totalBounced, totalOpened, totalClicked, totalUnsubscribed, totalComplained);
}
function selectHandler() {
var selectedItem = contactsStatisticsChart.getSelection()[0];
var value = contatatsStatisticsData.getValue(selectedItem.row, 0);
alert('The user selected ' + value);
}
function getEmailCampaign(url, queryString) {
$.ajax({
url: url,
data : queryString,
dataType: "json",
type: "POST",
success: function(response) {
if (!$.isEmptyObject(response)) {
showEmailCampaignStatistics(response);
} else {
}
}, error: function(xhr, status, error){
if (xhr.status == 500) {
var errorResponse = xhr.responseText;
if (errorResponse) {
try {
var jsonErrorResponse = $.parseJSON(errorResponse);
var actionErrors = jsonErrorResponse.actionErrors;
var errorMessage = actionErrors.join();
alert(errorMessage);
} catch(err) {
alert(arr.message);
alert(errorResponse);
}
}
}
}
});
}
getEmailCampaign(getEmailCampaignUrl, queryString);
})(jQuery); //end of (function($))
</script>
Upvotes: 1
Views: 2361
Reputation: 61275
this happens when you try to use google charts before it has completely loaded.
in this case, getEmailCampaign
is being called first,
which eventually calls drawContactsStatisticsChart
,
all which happens before google.charts.load
has finished.
plus, there is no reason to set the google callback to drawContactsStatisticsChart
,
because it won't pass all the args the function needs.
instead, wait on the callback before calling getEmailCampaign
.
recommend setup as follows...
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script language="JavaScript" type="text/javascript">
(function($) {
var contatatsStatisticsData;
var contactsStatisticsChart;
var emailCampaignId = 1;
var stepId = 0;
var queryString = "emailCampaignId=" + emailCampaignId + "&stepId=" + stepId ;
var getEmailCampaignUrl = "/mailgun/getAggregatedStats.htm";
// Load the Visualization API and the corechart package.
google.charts.load("current", {packages:["corechart"]});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(function () {
getEmailCampaign(getEmailCampaignUrl, queryString);
});
function drawContactsStatisticsChart(totalDelivered, totalBounced, totalOpened, totalClicked, totalUnsubscribed, totalComplained) {
contatatsStatisticsData = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['DELIVERED = ' + totalDelivered, totalDelivered],
['BOUNCED = ' + totalBounced, totalBounced],
['OPENED = ' + totalOpened, totalOpened],
['CLICKED = ' + totalClicked, totalClicked],
['UNSUBSCRIBED = ' + totalUnsubscribed, totalUnsubscribed],
['COMPLAINED = ' + totalComplained , totalComplained]
]);
// Set chart options
var options = {
title: 'My Campaign Statistics',
is3D: true,
};
// Instantiate and draw our chart, passing in some options.
contactsStatisticsChart = new google.visualization.PieChart(document.getElementById('pieChart_3d'));
google.visualization.events.addListener(contactsStatisticsChart, 'select', selectHandler);
contactsStatisticsChart.draw(contatatsStatisticsData, options);
}
function showEmailCampaignStatistics(response) {
var totalDelivered = response.totalDelivered;
var totalBounced = response.totalBounced;
var totalOpened = response.totalOpened;
var totalClicked = response.totalClicked;
var totalUnsubscribed = response.totalUnsubscribed;
var totalComplained = response.totalComplained;
drawContactsStatisticsChart(totalDelivered, totalBounced, totalOpened, totalClicked, totalUnsubscribed, totalComplained);
}
function selectHandler() {
var selectedItem = contactsStatisticsChart.getSelection()[0];
var value = contatatsStatisticsData.getValue(selectedItem.row, 0);
alert('The user selected ' + value);
}
function getEmailCampaign(url, queryString) {
$.ajax({
url: url,
data : queryString,
dataType: "json",
type: "POST",
success: function(response) {
if (!$.isEmptyObject(response)) {
showEmailCampaignStatistics(response);
} else {
}
}, error: function(xhr, status, error){
if (xhr.status == 500) {
var errorResponse = xhr.responseText;
if (errorResponse) {
try {
var jsonErrorResponse = $.parseJSON(errorResponse);
var actionErrors = jsonErrorResponse.actionErrors;
var errorMessage = actionErrors.join();
alert(errorMessage);
} catch(err) {
alert(arr.message);
alert(errorResponse);
}
}
}
}
});
}
})(jQuery); //end of (function($))
</script>
Upvotes: 1