Basit
Basit

Reputation: 8626

When trying to create google charts Getting error Uncaught TypeError: Cannot read property 'arrayToDataTable' of undefined

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

Answers (1)

WhiteHat
WhiteHat

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

Related Questions