9

I have a Ruby on Rails JSON question.

I have what I think is a strange error. I have the following JSON string which I get like this from an external API

test = "[{'domain': 'abc.com'}, {'domain': 'def.com'}, {'domain': 'ghi.com'}]"

Now, I want to convert this string to a hash using:

hash = JSON.parse test

The problem is that it errors with:

JSON::ParserError: 419: unexpected token at '{'domain': 'abc.com'}, {'domain': 'def.com'}, {'domain': 'ghi.com'}]'

The problem now with just replacing ' with " is dangerous if any strings includes ' or ". Anyone have a solution?

3
  • You could do JSON.parse test.gsub("'", '"'). This will remove all the single quotes, and then parse the string Commented Jan 12, 2016 at 5:39
  • I get this JSON from an external API so your solution is probably the best way. Thanks! Commented Jan 12, 2016 at 5:47
  • However, there might be a problem if there is a ' or '"' in the json values, replacing all ' to " can break the json.... anyone have a solution? Commented Jan 12, 2016 at 5:50

4 Answers 4

13

It's most likely because this isn't valid JSON. Change your single quotes to double quotes, like so:

test = '[{"domain": "abc.com"}, {"domain": "def.com"}, {"domain": "ghi.com"}]'

An explanation can be found here, and you can validate your JSON here.

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

4 Comments

The problem is that I am getting it like this from an external API. Is there a safe way to "convert" it to real JSON? Just replacing the 'is dangerous.
You're correct about "just replacing the '" being dangerous. There isn't a great way to do it, unfortunately. I strongly suggest emailing the API provider (or filing an issue if they have some such system set up) and telling them that their API is incompatible with all strict JSON parsers (which is likely to include Ruby, Java, Python, PHP, .NET—just about everything except calling eval in a JavaScript runtime, a risk no sane developer will want to take).
I solved it (ugly fix which should be pretty safe) with JSON.parse test.gsub("{'", '{"').gsub("':'", '":"').gsub("' : '", '":"').gsub("' :'", '":"').gsub("': '", '":"').gsub("'}", '"}').gsub("':", '":').gsub(", '", ',"').gsub(",'", ',"').gsub("' ,", '",').gsub("',", '",').gsub("u'", '"').gsub("']", '"]').gsub("['", '["')
That is ugly, and honestly shouldn't be used as a production solution. I agree with Jordan: speak to whoever provides the API. It's their responsibility to create something their users can consume (which it currently is not doing). Is this a commercial API?
7

Using Rails 4 or above, If you want to have symbol keys instead of string keys, you can use deep_symbolize_keys method

hash = JSON.parse(test).deep_symbolize_keys

That's in addition that the real problem was invalid json as MyCah mentioned.

Comments

6

You're getting an error because your string isn't valid JSON. In JSON all property names must be double-quoted and string values must also be double-quotes. Single-quotes are never valid.

test = '[{"domain": "abc.com"}, {"domain": "def.com"}, {"domain": "ghi.com"}]'
JSON.parse(test)
# => [ { "domain" => "abc.com" },
#      { "domain" => "def.com" },
#      { "domain" => "ghi.com" } ]

Comments

0

Use this piece of code. you are missing ActiveSupport::JSON

  ActiveSupport::JSON.decode json_string

1 Comment

Tried: hash = ActiveSupport::JSON.decode test. Same error, sorry.

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.