views:

1483

answers:

2

I have a web service that uses Python's SimpleJSON to serialize JSON, and a javascript/ client that uses Google's Visualization API. When I try to read in the JSON response using Google Data Table's Query method, I am getting a "invalid label" error.

I noticed that Google spreadsheet outputs JSON without quotes around the object keys. I tried reading in JSON without the quotes and that works. I was wondering what was the best way to get SimpleJSON output to be read into Google datable using

query = new google.visualization.Query("http://www.myuri.com/api/").

I could use a regex to remove the quotes, but that seems sloppy. The javascript JSON parsing libraries I've tried won't read in JSON syntax without quotes around the object keys.

Here's some good background reading re: quotes around object keys:

http://simonwillison.net/2006/Oct/11/json/.

+2  A: 

Are you certain the Google API is expecting JSON? In my experience Google's APIs tend not to be massively broken in a manner you're describing -- it could be that they're actually expecting a different format that merely resembles JSON.


Further poking around reveals instructions for retrieving data in the format Google expects:

For example, to get the dataSourceUrl from a Google Spreadsheet, do the following:

  1. In your spreadsheet, select the range of cells.
  2. Select 'Insert' and then 'Gadget' from the menu.
  3. Open the gadget's menu by clicking on the top-right selector.
  4. Select menu option 'Get data source URL'.

I did this and opened the URL in my browser. The data it was returning was certainly not JSON:

google.visualization.Query.setResponse(
{requestId:'0',status:'ok',signature:'1464883469881501252',
table:{cols: [{id:'A',label:'',type:'t',pattern:''},
{id:'B',label:'',type:'t',pattern:''}],
rows: [[{v:'a'},{v:'h'}],[{v:'b'},{v:'i'}],[{v:'c'},{v:'j'}],[{v:'d'},{v:'k'}],[{v:'e'},{v:'l'}],[{v:'f'},{v:'m'}],[{v:'g'},{v:'n'}]]}});

It looks like the result is intended to be directly executed by the browser. Try modifying your code to do something like this:

# old
return simplejson.dumps ({"requestId": 1, "status": "ok", ...})

# new
json = simplejson.dumps ({"requestId": 1, "status": "ok", ...})
return "google.visualization.Query.setResponse(%r);" % json
John Millikin
I tried wrapping the json with Query.setResponse(). The Invalid label error goes away, but now something is timing out along the way. I do query.send and in the callback I execute response.DataTable(). It looks like it times out there.I think it's the right direction though.
thaiyoshi
+1  A: 

The "invalid label" error is usually due to a blind eval() on the JSON string, resulting in property names being mistaken as labels (because they have the same syntax -- "foo:").

eval("{ foo: 42, bar: 43 }"); // Results in invalid label

The quick remedy is to make sure your JSON string has parenthesis enclosing the curly braces:

eval("({ foo: 42, bar: 43 })"); // Works

Try enclosing your JSON string in parenthesis to see if the "invalid label" error goes away.

Ates Goral
Wrapping JSON in parens makes it invalid.
John Millikin
That's why I say "try". It's a troubleshooting step to try to see if the "invalid label" error has anything to do with it.
Ates Goral
Also, it's just meant as a preprocessing step; you're not supposed to include the parenthesis in your original JSON. Anyway, it's rather a moot point since you're not supposed to use eval() in the first place :)
Ates Goral