简体   繁体   中英

Google Charts - DataTable Issue with API Request and jQuery

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>

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 (ie 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});});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM