0

I tried to decode and parse the string that an API returns, however the syntax of the returned JSON object is weird.

I could just strip elements from the string, but was wondering what is the best way to clean up this JSON string and convert it to a Ruby hash?

"DataCallBack([
    {
        \"detail1\": \"result1\",
        \"detail2\": \"result2\",
        \"Attr1\": [
            {
                \"detail1\": \"result1\",
                \"detail2\": \"result2\",
            },
            {...}
        ]
        ],
        \"Attr2\": [
            {
                \"detail1\": \"result1\",
                \"detail2\": \"result2\",
            },
            {...}
        ]
    }
])"
8
  • 1
    This seems like just serialized JSONP string. Commented Jan 3, 2014 at 20:54
  • 1
    That's not "weird", that's a regular JSON string with it's quotes escaped. It's possible it's just being rendered that way, and the backslashes don't actually exist within the string; have you tried JSON.parse? Commented Jan 3, 2014 at 20:55
  • 1
    It is a serialized JSONP string I think, but when I try JSON.parse or decode I get JSON::ParserError: 795: unexpected token at 'DataCallBack... Commented Jan 3, 2014 at 20:58
  • 1
    You sure you can't get a version without the DataCallBack wrapper callback? JSONP is really only designed to work with javascript. Commented Jan 3, 2014 at 21:00
  • 1
    Most APIs that support JSONP also support raw JSON. So if you are querying an API from your server, and not from AJAX, you typically don't pass the callback parameter and get raw JSON that you can directly parse. JSONP is simply a workaround that allows cross domain fetching of data in a browser. Commented Jan 3, 2014 at 21:09

2 Answers 2

1

Just request the data without the ?callback=DataCallBack in the query string, and you will probably get raw JSON that you can directly parse.

Sign up to request clarification or add additional context in comments.

Comments

0

It's easy to strip the JSON from a JSONP response:

jsonp = 'DataCallBack([
    {
        "detail1": "result1",
        "detail2": "result2",
        "Attr1": [
            {
                "detail1": "result1",
                "detail2": "result2"
            }
        ],
        "Attr2": [
            {
                "detail1": "result1",
                "detail2": "result2"
            }
        ]
    }
])'

require 'json'
JSON.parse(jsonp[/{.+}/m])
# => {"detail1"=>"result1",
#     "detail2"=>"result2",
#     "Attr1"=>[{"detail1"=>"result1", "detail2"=>"result2"}],
#     "Attr2"=>[{"detail1"=>"result1", "detail2"=>"result2"}]}

Your JSONP sample was mangled a bit, probably by trying to shorten it, so I cleaned it up to be valid JSON.

The pattern /{.+}/m tells the regular expression engine to find everything contained by the outermost curly braces, which is the JSON. The m flag tell the engine to treat the whole string, containing line-ends, as a long string, which is necessary when using . because it won't normally match line-ends. At that point you'll have the JSON content, so then it's a simple matter of parsing it back into a Ruby object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.