1

I have the following code:

$.ajax({
    async: false,
    url: 'chart_data.php',
    data: {'option':'high', 'id':id},
    dataType: 'json',
    success: function(response){
        alert('in');
        var data = google.visualization.arrayToDataTable(response);
        var options= { curveType:'none', width: 300, height: 200, hAxis: {title:'Years'}, vAxis: {title:'Value'}, title: 'High Time - Low Value' };
        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
        chart.draw(data, options);  
    }
});

in a webpage. I'd like the chart to display, based on a drop-down menu. The rest of the function works just fine. I checked in Firebug, and the JSON response comes through with a 200 OK status message. In fact, I can see all the JSON just fine in Firebug.

The question remains, why does the alert('in'); never get triggered, and why doesn't google load it's chart into the associated chart div?

Edit:

I get the following error when adding an error callback: parseerror SyntaxError: JSON.parse: unexpected character.

This is the JSON response from the server:

[['Year', 'Low', 'High'],['1984', 318000, 395000],['1984', 418000, 495000],
['1984', 380000, 450000],['1984', 410000, 460000],['1984', 410000, 460000],
['1985', 435000, 485000],['1985', 435000, 485000],['1985', 435000, 485000],
['1985', 435000, 485000],['1985', 435000, 485000],['1985', 435000, 485000],
['1985', 435000, 485000],['1985', 435000, 485000],['1985', 318000, 395000],
['1985', 418000, 495000],['1985', 380000, 450000],['1985', 420000, 470000],
['1985', 420000, 470000]]

It looks correct to me, although I am not 100% certain on JSON structure.

Edit:

I have made a few changes, and it seems that I am getting a little further along. First, I removed the header('Content-type: application/json'); line from my php script. I then changed the dataType: 'json' to dataType: 'html'.

It now loads the success callback in the $.ajax() call. It doesn't like the text response when I try to send that to Google's arrayToDataTable() method.

If I can get the returned string (which looks like the above JSON response that isn't actually a JSON response) to be parsed into a javascript array, then I'd be golden. I hope.

Edit:

I ended up using an eval statement in my success callback to turn the http response into an array eval('var res = ' + response); This is probably not the best way to do this. If someone has a better (and more secure) way of doing this, that'd be great.

Edit:

I didn't really like using the eval statement, so I looked into other ways of changing the return string into an array. I didn't really care for any of them until I ran across this little gem:

response = JSON.parse(response);

This works without issue.

Thanks for everyone's assistance.

Jim P
  • 534
  • 2
  • 8
  • 24
  • are you getting any errors in the console? – mason81 Jun 12 '12 at 19:12
  • 1
    You did not specify a type i.e. POST or GET. – Charles Jun 12 '12 at 19:12
  • I get no errors in the console in Firebug. Additionally, the response coming back is JSON according to Firebug. The response data looks nice, and I can copy/paste it right into a chart and it displays the chart. The problem is that it is never actually getting into the success callback. – Jim P Jun 12 '12 at 19:13
  • 4
    @clockwork189, You don't have to specify, default is GET, so unless you want POST then you have to define that. – Gabe Jun 12 '12 at 19:14
  • 1
    Aha, my apologies for miscommunication, but yes @Gabe what I meant was it could be a post request and it is been defaulted at GET – Charles Jun 12 '12 at 19:16
  • Why are you using `async: false`? It's basically useless, in jQuery 1.8 it is being deprecated. I only ask because it could be holding up the browser rendering and causing unexpected results. – Terry Jun 12 '12 at 19:17
  • 4
    You could try adding a `error` callback to see and print the eventual info you can get. – albinohrn Jun 12 '12 at 19:17
  • @Terry: I am using `async: false` because if I don't, other elements on the page fail to render at all. Possibly because of timeout issues. It was just thrown in there to help fix that issue for the time being, and I plan on revisiting it once I get other portions of the app working correctly. – Jim P Jun 12 '12 at 20:27

2 Answers2

1

OK no one has answered yet so I'll give it a shot here. It looks like you've updated with an error message and the return value that you are getting from the ajax call.

The problem is that what you are receiving is not a JSON object, but rather a javascript array. JSON objects will be encased in curly brackets { and } while arrays are encased in square brackets [ and ].

You should modify the script you are calling via ajax so that it returns a proper JSON object (using json_encode in php is quite handy).

You will want your response to look more like this:

{"data":[["Year", "Low", "High"],["1984", 318000, 395000],["1984", 418000, 495000],
["1984", 380000, 450000],["1984", 410000, 460000],["1984", 410000, 460000],
["1985", 435000, 485000],["1985", 435000, 485000],["1985", 435000, 485000],
["1985", 435000, 485000],["1985", 435000, 485000],["1985", 435000, 485000],
["1985", 435000, 485000],["1985", 435000, 485000],["1985", 318000, 395000],
["1985", 418000, 495000],["1985", 380000, 450000],["1985", 420000, 470000],
["1985", 420000, 470000]]}

According to google, they are looking for something like this:

{
   cols: [{id: 'task', label: 'Task', type: 'string'},
          {id: 'hours', label: 'Hours per Day', type: 'number'}
   ],
   rows: [{c:[{v: 'Work'}, {v: 11}]},
          {c:[{v: 'Eat'}, {v: 2}]},
          {c:[{v: 'Commute'}, {v: 2}]},
          {c:[{v: 'Watch TV'}, {v:2}]},
          {c:[{v: 'Sleep'}, {v:7, f:'7.000'}]}
   ]
 }

So, perhaps you actually need to rework your data to follow this structure first? Something like this:

{
  "cols": [{"id":"year", "label":"Year", "type":"string"},
         {"id":"low",  "label":"Low",  "type":"string"},
         {"id":"high", "label":"High", "type":"string"}],
  "rows": [{"c":[{"v":"1984"}, {"v":"318000"}, {"v":"395000"}]},
         {"c":[{"v":"1984"}, {"v":"418000"}, {"v":"495000"}]},
         {"c":[{"v":"1984"}, {"v":"380000"}, {"v":"450000"}]},
         {"c":[{"v":"1985"}, {"v":"420000"}, {"v":"470000"}]}]
}

If JSON seems a bit confusing you can read more about it here: http://www.json.org/

EDIT

Considering I overlooked the .arrayToDataTable() function call, I guess I should have quoted this example from Google's documentation (link is already referenced above):

// Version 1: arrayToDataTable method
var data2 = google.visualization.arrayToDataTable([
  ['Country', 'Population', 'Area'],
  ['CN', 1324, 9640821],
  ['IN', 1133, 3287263],
  ['US', 304, 9629091],
  ['ID', 232, 1904569],
  ['BR', 187, 8514877]
]);

Since your array is coming in like this:

[['Year', 'Low', 'High'],
 ['1984', 318000, 395000],
 ['1984', 418000, 495000],
 ['1984', 380000, 450000],
 ['1984', 410000, 460000],
 ['1984', 410000, 460000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 435000, 485000],
 ['1985', 318000, 395000],
 ['1985', 418000, 495000],
 ['1985', 380000, 450000],
 ['1985', 420000, 470000],
 ['1985', 420000, 470000]]

Which appears to be properly formatted, I think you should try changing your "dataType" in your ajax call to "text" instead of "json" since you are really returning an array and not a JSON object. This should solve your problem.

mason81
  • 1,730
  • 2
  • 18
  • 33
  • Thanks, I will give this a try later today. It's been a bit of a pain trying to get this to work correctly. – Jim P Jun 20 '12 at 17:34
  • So I tried putting {} around the block of data instead of []. This gives me a parserror: JSON.parse: expected property name or '}' instead of the unexpected character. As to the google format, I am using googles .arrayToDataTable() method to generate the data from an array of values. – Jim P Jun 20 '12 at 17:39
  • OK I added the answer. Please take a look at the last half of my answer, I think just changing your dataType in your ajax call to "text" should solve your problem. – mason81 Jun 21 '12 at 16:25
  • It was still having issues with the arrayToDataTable() method, but after putting it in `response = JSON.parse(response);`, there was not an issue in getting it to work. I do, however, wonder why jQuery's parseJSON() method was having such a hard time with the string. – Jim P Jun 21 '12 at 19:25
  • which version of jquery are you using? here is a SO post/answer about the difference between the two functions: http://stackoverflow.com/questions/10362277/jquery-parsejson-vs-json-parse – mason81 Jun 21 '12 at 19:49
1

There is an error in the formatting of your JSON, string must be double quoted (") and not single quoted (')

If you want to check that your JSOn is valid, you can use this

  • Thanks for that. I may test it out later since I don't really want to have an eval statement just laying about in production code. – Jim P Jun 20 '12 at 20:33