JSON Parsing a Redis.get return - ruby

I'm storing some data in Redis and when I retrieve this data I'm having trouble parsing it.
When I run this:
$redis.get("data") I get this: "[{\"login\"=>\"name\", \"id\"=>1574}]"
When I try to use JSON.parse against the return body I get this error:
JSON::ParserError: 409: unexpected token at '{"login"=>"name", "id"=>1574}]'
What am I doing wrong?

You need to first serialize your ruby object into JSON before storing it in redis.
In this case you would need to call $redis.set('data', JSON.dump(data)) instead of what is currently being called, which is $redis.set('data', data.to_s). The .to_s gets called on whatever object is passed into redis' set method.
If you really need to parse the data you have already stored then you can use ruby's eval, although you should not use this in production!
$ data = eval($redis.get('data'))
=> [{"login"=>"name", "id"=>1574}]
$ $redis.set('data', JSON.dump(data))

"[{\"login\"=>\"name\", \"id\"=>1574}]"
is not json string
If you want to deserialize string then you write this.
"[{\"login\":\"name\", \"id\":1574}]"
=> is changed to :
So, you need to modify the creation JSON string.

Related

Parsing JSON with a Javascript Date object in Ruby

I am using a SOAP API that returns XML but with JSON strings within the response envelope. For most of the API calls this has not been a problem but there is one that returns Javascript new Date objects that is causing problems when using JSON.parse. Here is a simplified example of the response I am getting.
"{\"History\":[ {\"Timestamp\":new Date(1380024020923)}]}"
When using JSON.parse I get the following error.
JSON::ParserError: 399: unexpected token at '{"Timestamp":new Date(1380024020923)}]}'
Is there a nice way to parse this string or am I going to have to use some regex/string trickery? Has anyone come across this way of returning a date object and I would like to understand the advantage?

Minimum input for JSON parse

I am deserializing strings using JSON.parse. Most of the time, I have a contentful object serialized into a string, and JSON.parse works on that string, but in some cases, I want to send a minimum input to JSON.parse, whose result will just be thrown away. When I send "" like: JSON.parse(""), it returns an error: unexpected token at '""'. What is the restriction of JSON specification that I am violating, and what alternative minimum string can I send to JSON.parse?
Reading the JSON specification that Musa provided a link to, one minimum object that can be stringified and sent to JSON seems to be:
[null]
or something like that. Or, in the stringified form, it will be:
"[null]"
I would send null as this represents "nothing".
require 'json'
nil.to_json
#=> "null"

Parse JSON from Jenkins, once hash, then nil

Jenkins gives me JSON from http://jenkins.net/jobs/MyJob/lastBuild/api/json
Then I use HTTParty to get it like so:
response = self.get( url, options )
change = response['changeSet']['items'][0]
This gives me the content of the last changes. change.class returns "Hash".
If I try this:
change = response['changeSet']['items'][0]['revision']
as looking at the JSON suggests, I get "Undefined method '[]' on NilObject".
What am I doing wrong?
EDIT3:
Of course, the problem lies between User and keyboard. The method was first called on another JSON, because it's polling the changes for more than one project, and one of the returned JSON objects didn't contain those keys. D'oh!
Sorry.
If you get that kind of error you're hitting an empty key and then trying to use it as if it's populated. Without seeing what your JSON is, it's hard to say, but one of those is failing. You'll want to inspect these:
response['changeSet']
response['changeSet']['items']
response['changeSet']['items'][0]
If any of those end up being nil then you can pin-point the problem. JSON comes back as an arbitrary structure so chaining a bunch of calls together without any sort of testing can lead to trouble.

Should a JSON-P callback function accept a string?

I'm calling a REST API somebody else created. It supports JSONP to facilitate cross domain access.
The response I get back from the service looks like:
mycallback('{"token": "123456789"}');
Notice the single quotes wrapping the JSON data; Passing it as a string rather than a raw object. JQuery can handle this, but other libraries seem to expect a raw object instead.
mycallback({"token": "123456789"});
The raw object parameter makes more sense to me since it avoids the need to parse the JSON data, but I want to know for sure before asking the maintainer of the API to make the adjustment:
Which is most correct?
Passing a javascript literal (second) as shown here is more correct as it avoids deserializing the string back to a javascript object.
Passing a string is obviously a bad thing - you have two choices (#1 is preferred):
Ask the developer of the JSONP service to send proper JSONp instead of a string
Make your callback function smart so it uses something like payload = JSON.parse(payload); in case payload is a string.

Decode a YAML serialized object

I have serialized an object in YAML and send it to a remote worker.
The worker doesent have the object definition so i get a YAML::Object.
How can i access the field inside it?
A text field seems like that base64 encoded, how can i decode that? (no, decode64 not works).
you can pass the object as something "known between both sides" (like an openstruct or hash) or give the description to the client.
It would be interesting to have a serialization format that also serialized the class and its methods...I'll have to think about that one...
try c["bar"]
you can also see all the provided keys using c.keys

Resources