Home » Php » javascript – Google Charts – DataTable Issue with API Request and jQuery

javascript – Google Charts – DataTable Issue with API Request and jQuery

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am struggling mightily with what should be a simple AJAX call to an API that renders back DataTable formatted data (Google Visualization API Reference) for insertion into a Google Chart. The data is successfully received via the AJAX call and I can alert the response to the browser with no issue. However, when I pass in the same exact variable chartData – I’m met with an error in the console:

Uncaught (in promise) SyntaxError: Unexpected token c in JSON at position 1
at JSON.parse ()

I’ve placed the code I’m using below; any assistance would be significantly appreciated.

FRONT END [charts-testing.php]

<html>
    <head>
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
        <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
        <script type="text/javascript">
            google.charts.load('current', {'packages':['corechart']});
            google.charts.setOnLoadCallback(drawChart);
            function drawChart() {
                var chartData = $.ajax({
                    url: "includes/processing/process_chart_data.php",
                    async: false, 
                }).responseText;

                alert(chartData);
                var data = new google.visualization.DataTable(chartData);
                var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
                chart.draw(data, {width: 400, height: 240});
        }
        </script>
    </head>
    <body>
        <div id="chart_div"></div>
    </body>
</html>

BACK END [process-chart-data.php]

<?php
include_once '../classes/clsAPI.php';
$objAPI = new clsAPI();

$api = [redacted]
$chartData = $objAPI->getDataTable($api);

header('Content-Type: text/plain');
echo $chartData;
?>

RESPONSE FROM process-chart-data.php

{cols:[{id:'AgeRange',label:'Age Range',type:'string'},{id:'MemberCount',label:'Member Count',type:'number'}],rows:[{c:[{v:'18-34'},{v:200}]},{c:[{v:'35-44'},{v:200}]},{c:[{v:'45-54'},{v:400}]},{c:[{v:'55-64'},{v:500}]},{c:[{v:'65-74'},{v:600}]}]}

REQUEST HEADERS

GET /includes/processing/process_chart_data.php HTTP/1.1
Host: local.site.com
Connection: keep-alive
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36
Referer: http://local.site.com/charts-testing.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,fr;q=0.8

RESPONSE HEADERS

HTTP/1.1 200 OK
Date: Thu, 13 Feb 2020 07:08:12 GMT
Server: Apache/2.2.34 (Unix) mod_wsgi/3.5 Python/2.7.13 PHP/7.2.10 mod_ssl/2.2.34 OpenSSL/1.0.2o DAV/2 mod_fastcgi/mod_fastcgi-SNAP-0910052141 mod_perl/2.0.9 Perl/v5.24.0
X-Powered-By: PHP/7.2.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 247
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/plain;charset=UTF-8

It should also be noted that by replacing chartData with the exact response from the API (no formatting), it renders the chart without error.

EDIT

To illustrate the response from the API call working if manually injected into the Visualization call, see below. This successfully displays the chart and is identical to the value of var chartData:

<html>
    <head>
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
        <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
        <script type="text/javascript">
            google.charts.load('current', {'packages':['corechart']});
            google.charts.setOnLoadCallback(drawChart);

            function drawChart() {
                var chartData = $.ajax({
                    url: "includes/processing/process_chart_data.php",
                    async: false, 
                }).responseText;

                alert(chartData);
                var data = new google.visualization.DataTable({cols:[{id:"AgeRange",label:"Age Range",type:"string"},{id:"MemberCount",label:"Member Count",type:"number"}],rows:[{c:[{v:"18-34"},{v:200}]},{c:[{v:"35-44"},{v:200}]},{c:[{v:"45-54"},{v:400}]},{c:[{v:"55-64"},{v:500}]},{c:[{v:"65-74"},{v:600}]}]});
                var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
                chart.draw(data, {width: 400, height: 240});
        }
        </script>
    </head>
    <body>
        <div id="chart_div"></div>
    </body>
</html>
How to&Answers:

it appears that Google Visualization API doing json.parse on your data response from server so

$objAPI->getDataTable should output your JSON object like this

instead of using ‘cols’ for strings and object elements name use “cols”

  cols: [{id: 'A', label: 'NEW A', type: 'string'}]

use this

"cols": [{"id":"A", "label": "NEW A", "type": "string"}]

also why using async:false

take a look at this
you should use async then call on-success success:function(data){/*call chart foramtting*/}

async (default: true) Type: Boolean By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: “jsonp” requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active. As of jQuery 1.8,
the use of async: false with jqXHR ($.Deferred) is deprecated; you
must use the success/error/complete callback options instead of the
corresponding methods of the jqXHR object such as jqXHR.done().

or

$.get('includes/processing/process_chart_data.php', function (chartData) {
var data = new google.visualization.DataTable(chartData);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});});