Cannot convert Hash to String? - ruby

I am trying to parse the JSON response from Wordnik's API. This is built with Sinatra. I keep getting the error "TypeError at /word" "can't convert Hash into String". Am I using the json parser incorrectly?
Here's my code:
get '/word' do
resp = Wordnik.words.get_random_word(:hasDictionaryDef => 'true', :maxCorpusCount => 20, :minLength => 10)
result = JSON.parse(resp)
word = result.word
return word.to_s
end

You are probably getting a hash. To convert it use to_json:
JSON.parse(resp.to_json)

You have not given what's the JSON response that you are parsing. But assuming it is something of the form
{
"word":"my_word"
}
you need to do result["word"] to get the value after parsing the JSON response.

Related

Storing JSON from API which has null values

I'm trying to save null value in JSON into postgresql. When I use the following code:
resume = Resume.create!({
parsedres: {"Resume":{"xml:lang":"en","xmlns":"http://ns.hrxml.org/2006-02-28","xmlns:vos":"http://noresm.com/hr-xml/2006-02-28","ResumeId":{"IdValue":null}}}
})
I get an error:
NameError: undefined local variable or method `null' for main:Object
The issue is I get API data without "" for null and when I use JSON.parse
resume.parsedres = JSON.parse(response.body)
resume.save
It throws the
JSON::ParserError: 765: unexpected token at '<ParseResumeResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Code>Ack</Code><SubCode>Authentication/SubCode><Message>AccountID.</Message><CreditsRemaining>100</CreditsRemaining></ParseResumeResponse>'
Why does JSON.parse not interpret null?
In the first example you provided, the parsedres is not JSON but a Ruby Hash literal. Since the literal is Ruby code, you'd need to use Ruby's nil keyword instead of null:
resume = Resume.create!({
parsedres: {"Resume":{"xml:lang":"en","xmlns":"http://ns.hrxml.org/2006-02-28","xmlns:vos":"http://noresm.com/hr-xml/2006-02-28","ResumeId":{"IdValue":nil}}}
})
If you received a JSON string from the API, you should be able to parse it using the code you listed above:
require 'json'
resume = Resume.create!({
parsedres: JSON.parse('{"Resume":{"xml:lang":"en","xmlns":"http://ns.hrxml.org/2006-02-28","xmlns:vos":"http://noresm.com/hr-xml/2006-02-28","ResumeId":{"IdValue":null}}}')
})
Based on the exception being thrown, it looks like the response.body is XML data, not JSON.

how do I parse out this URL-encoded string with a JSON array using Ruby?

When I use a webhook with Mandrill and post to my Iron Worker, I get the following Raw (this is from RequestBin, as well) -- I didn't include the whole payload, just an example:
puts payload =>
mandrill_events=%5B%7B%22event%22%3A%22inbound%22%2C%22msg%22%3A%7B%22dkim%22%3A%7B%22signed%22%3Atrue%2C%22valid%22%3Atrue%7D%2C%22email%22%3A%22kaya%40hellokaya.com%22%2C%22from_email%22%3A%22example.sender%40mandrillapp.com%22%2C%22headers%22%3A%7B%22Content-Type%22%3A%22multipart%5C%2Falternative%3B+boundary%3D%5C%22_av-7r7zDhHxVEAo2yMWasfuFw%5C%22%22%2C%22Date%22%3A%22Fri%2C+10+May+2013+19%3A28%3A20+%2B0000%22%2C%22Dkim-Signature%22%3A%5B%22v%3D1%3B+a%3Drsa-
I tried to extract the value of the parameter mandrill_events using:
puts params = CGI::parse(#payload) =>
{"mandrill_events"=>["[{\"event\":\"inbound\",\"msg\":{\"dkim\":{\"signed\":true,\"valid\":true},\"email\":\"kaya#hellokaya.com\",\"from_email\":\"example.sender#mandrillapp.com\",\"headers\":{\"Content-Type\":\"multipart\\/alternative; boundary=\\\"_av-7r7zDhHxVEAo2yMWasfuFw\\\"\",\"Date\":\"Fri, 10 May 2013 19:28:20 +0000\",\"Dkim-Signature\":[\"v=1; a=rsa-sha1; c=relaxed\\/relaxed; s=mandrill; d=mail115.us4.mandrillapp.com; h=From:Sender:Subject:List-Unsubscribe:To:Message-Id:Date:MIME-Version:Content-Type; i=example.sender#mail115.us4.mandrillapp.com;
Then I am stuck. I want to extract the email value in the JSON.array.
I thought to try the following;
puts json_params = JSON.parse(params)
But I am now feeling there must be a better way....
How can I extract the elements from the JSON array in this URL-encoded string?

how to get each value from json in ruby sinatra?

I need to extract each key-value of json and that value should save in database. but i am getting trouble in getting value of each key in json.
JSON
{
"topo": [
{
"dpid": "00:00:00:00:00:00:00:03",
"ports": [
3,
1
]
}
],
"app": "vm_migration"
}
code
post '/save_summary', :provides => :json do
begin
params = JSON.parse(request.env["rack.input"].read)
return params["topo"][0]["dpid"]
#above code return correct value
return params["topo"][0]["ports"] #this is not working
rescue Exception => e
return e.message
end
end
i don't know what's wrong with ports statement, please help me to figure out small issue.
What you are returning – params["topo"][0]["ports"] – is an array of two elements, which is one of the things you can return from a Sinatra route:
An Array with two elements: [status (Fixnum), response body (responds to #each)]
So you are trying to return a response with status 3 and body 1. The response body needs to be an object that responds to each, and 1 doesn’t. If you check your logs or console you will probably see an error undefined method `each' for 1:Fixnum. Assuming you just want to see the array in the browser, simply convert it to a string:
return params["topo"][0]["ports"].to_s
The first example works because params["topo"][0]["dpid"] is a string, and you can return strings from routes.

Issue on parsing string at JSON.parse

In controller side i am getting params like
"{\"violation_date\":\"sdfsdf\",\"violation_time\":\"\"},{\"violation_date\":\"sdfdsf\",\"violation_time\":\"sdfsdf\"},{\"violation_date\":\"1233\",\"violation_
time\":\"\"},{\"violation_date\":\"test\",\"violation_time\":\"time\"}"
class of this is String. I am trying to parse this. Through
JSON.parse(params_gotton)
Got
JSON::ParserError (757: unexpected token at ',{"violation_date":"sdfdsf","violation_time":"sdfsdf"},{"violation_date":"1233","violation_time":""},{"violation_d
te":"test","violation_time":"time"}'):
What i am doing wrong here. Any suggestions?
It's not valid json, this will work (use []):
require 'json'
jsn = '[{"violation_date":"sdfsdf","violation_time":""},
{"violation_date":"sdfdsf","violation_time":"sdfsdf"},
{"violation_date":"1233","violation_time":""},
{"violation_date":"test","violation_time":"time"}]'
JSON.parse(jsn) # => [{"violation_date"=>"sdfsdf", "violation_time"=>""}, {"violation_date"=>"sdfdsf", "violation_time"=>"sdfsdf"}, {"violation_date"=>"1233", "violation_time"=>""}, {"violation_date"=>"test", "violation_time"=>"time"}]
To verify json string you could use: http://www.jslint.com/.
And basic json structure: http://json.org/
UPDATED
In your case just try this:
JSON.parse('[' + params_gotton + ']')
well, received string does not contain a proper Json structure..
First convert that received param in a proper json structure and then parse it using "JSON.parse(params_gotton)".
In above received data all key and value shud be in a key value pair string format.. remove "\" symbol from received data..
it will definitely work fine..

Json Parse Error on parsing a hash

I am working on Ruby on Rails. I have a hash like below
{"attachment"=>"{:output_dir=>\"/home/mypath/\", :process_hash=>\"8b9d9c51\", :type=>\"pdf\", :processed_dir=>\"/513/9a1/88a\", :pdf=>\"/system/path/a3ae1194f76d737b6cfb141fa0fde17f78f2e94e.pdf\", :slides_count=>4, :meta=>{:swfs=>\"{/system/path/88a/8b9d9c51[*,0].swf,4}\", :pngs=>\"/system/path/8b9d9c51{page}.png\", :json=>\"/system/path/8b9d9c51.js\"}}"
In my code i have
JSON.parse(params[:attachment])
which throws me an error as
JSON::ParserError (757: unexpected token at '{:output_dir=>"/home/path", :process_hash=>"8b9d9c51", :type=>"pdf", :processed_dir=>"/513/9a1/88a", :pdf=>"/system/path/a3ae1194f76d737b6cfb141fa0fde17f78f2e94e.pdf", :slides_count=>4, :meta=>{:swfs=>"{/system/path/8b9d9c51[*,0].swf,4}", :pngs=>"/system/path/8b9d9c51{page}.png", :json=>"/system/path/8b9d9c51.js"}}'):
Suggest me how to resolve this.
JSON.parse parses an JSON formatted String into a Hash, not the other way around. I'm not sure what you'd like to accomplish?
If you're trying to convert a Hash into JSON (string) you could use
params[:attachment].to_json
If you're trying to convert a JSON (string) into Hash you could use
JSON.parse(params[:attachment])
However, your string doesn't look like JSON (it includes => where it should have :)
Valid JSON looks like:
{ "attachment": { "output_dir": "/home/mypath", "process_hash": "89r2432" } }

Resources