parsing JSON request - ruby-on-rails

The following #request = JSON.parse(request.body.read) is generating:
[
{
"application_id"=>"216",
"description"=>"Please double check date and time",
"release_date"=>"2018-12-01",
"auth"=>"someBigData"
}
]
However a blank is returned if invoking
Rails.logger.info #request['application_id']
and
if #request['auth'] == 'someBigData'
is generating a
TypeError (no implicit conversion of String into Integer):` in `app/controllers/base_controller.rb:55:in '[]'
What is wrong syntactically?

You're getting an array of hashes back, which is why #request['application_id'] returns a blank for you.
You'll need to do #request.first['application_id'] or #request[0]['application_id'] to index into your array.

As it's been already stated, you get this error cause #request is an array of hashes rather than a hash itself. To access "application_id" key of the first element you can also use dig method:
#request.dig(0, "application_id")
this way there is not going to be an exception in case #request is empty.

Related

How can I use JSON data with Ruby?

This seems really simple but I've looked all over and I can't find any documentation for this.
I have the following json file:
//data.json
{
"movie1": [
{"name": "Inception"}
]}
and I just want to print the value of name with Ruby.
json = File.read('data.json')
data = JSON.parse(json)
data['movie1']['name']
But I'm getting the error
"no implicit conversoin of String into Integer"
How can I print name?
"no implicit conversion of String into Integer" usually comes when you're trying to use an array as a hash. Array[] expects an index (integer). Your data is a hash inside an array inside a hash :
You need :
data['movie1'][0]['name']
or
data.dig('movie1', 0, 'name')

JSON::ParserError: 757: unexpected token at '{

the current hash is
{\"report_name\"=>\"Study/Control: ABIRATERONE ACETATE - 20151413355\", \"left_mue_start_date\"=>\"02-26-2015\", \"left_mue_end_date\"=>\"03-19-2015\", \"right_mue_start_date\"=>\"02-26-2015\", \"right_mue_end_date\"=>\"03-19-2015\", \"report_formulary_id\"=>\",7581\", \"mue\"=>\"true\", \"mue_type\"=>\"study/control\", \"chain_id\"=>\"1\", \"left_mue_formulary_ids\"=>[\"7581\"], \"action\"=>\"create_report\", \"controller\"=>\"informatics\", \"user_id\"=>339}
now I need to convert it in proper hash like
{"report_name" => "Study/Control: ABIRATERONE ACETATE - 20151413355"}
so I am trying to get it with JSON.parse but I am getting error like:
JSON::ParserError: 757: unexpected token at '{
So if someone know about that so please help me.
and I am using Rails 3.2
What you have is a hash printed as String. To convert it into a Hash use eval.
ch = "{\"report_name\"=>\"Study/Control: ABIRATERONE ACETATE - 20151413355\", \"left_mue_start_date\"=>\"02-26-2015\", \"left_mue_end_date\"=>\"03-19-2015\", \"right_mue_start_date\"=>\"02-26-2015\", \"right_mue_end_date\"=>\"03-19-2015\", \"report_formulary_id\"=>\",7581\", \"mue\"=>\"true\", \"mue_type\"=>\"study/control\", \"chain_id\"=>\"1\", \"left_mue_formulary_ids\"=>[\"7581\"], \"action\"=>\"create_report\", \"controller\"=>\"informatics\", \"user_id\"=>339}"
hash = eval(ch)
# => {"report_name"=>"Study/Control: ABIRATERONE ACETATE - 20151413355", "left_mue_start_date"=>"02-26-2015", "left_mue_end_date"=>"03-19-2015", "right_mue_start_date"=>"02-26-2015", "right_mue_end_date"=>"03-19-2015", "report_formulary_id"=>",7581", "mue"=>"true", "mue_type"=>"study/control", "chain_id"=>"1", "left_mue_formulary_ids"=>["7581"], "action"=>"create_report", "controller"=>"informatics", "user_id"=>339}
PS: A JSON string should look as follows, meaning what you have is not JSON and hence you got JSON::ParserError for using JSON.parse on a non-JSON string :
"{\"report_name\":\"Study/Control: ABIRATERONE ACETATE - 20151413355\",\"left_mue_start_date\":\"02-26-2015\",\"left_mue_end_date\":\"03-19-2015\",\"right_mue_start_date\":\"02-26-2015\",\"right_mue_end_date\":\"03-19-2015\",\"report_formulary_id\":\",7581\",\"mue\":\"true\",\"mue_type\":\"study/control\",\"chain_id\":\"1\",\"left_mue_formulary_ids\":[\"7581\"],\"action\":\"create_report\",\"controller\":\"informatics\",\"user_id\":339}"
To avoid using eval you could use JSON.parse ch.gsub('=>', ':') this way you will get a HASH from your HASH stored as STRING
Last time when I got this issue, since the json file that I got from a API that contains a BOM
UTF-8 BOM is a sequence of bytes (EF BB BF)
What's different between UTF-8 and UTF-8 without BOM?
at the beginning of that string, but you know that part wouldn't display or as readable when we got the string from response. I try to use Ruby JSON to parse it, but I failed, I got the same exception with yours. just a reminder for others, when you get a Json response. By the way, this would be no problem while you are handling that in javascript, but with problems in Python or Ruby languages.
I ran into a similar problem, though it was failing while parsing \"\". This is in regards to using Pact.IO. I mention it here since this is the highest ranked Google result while looking for the error I encountered. The solution in my case was to change the body of a POST in my C# application so that it wasn't using empty string, but a null string. Basically I added this before my HTTP call.
if (request.Method == HttpMethod.Post && request.Content!=null && request.Content.GetType()==typeof(StringContent) && request.Content.ReadAsStringAsync().Result == String.Empty)
request.Content = new StringContent(null);

Cannot access params map using Groovy

I want little help which I suspect is due to my lack of understanding for Groovy syntax. So, here's the thing:
On the GSP page I want to set a field's value from the params map which is
["id":"107901", "Field_10.value":"2", "Field_10":["value":"2"],"Field_11.value":"", "Field_11":["value":""],action:'abc']
On the gsp page, I want to find the value against the key Field_{some-id}.value
So I am calling a tag like, g.testTag(id:field.id) with its implementation as
def testTag = { attrs,body->
println "params are ${params}"
def result = ""
def keyRequired = "Field_${attrs.id}.value"
println "keyRequired >>>>> ${keyRequired.toString()}"
params.each { key,value->
println "key is ${key}"
println "Value is ${value}"
if (key.equals(keyRequired.toString())) {
result = params.value
}
}
println "Final result is >>>>>> ${result}"
}
The value passed in id is 10 and with my params printed as above, I was expecting a value
of 2 which is corresponding to the key in the params to show up. But apparently I see the
result as null..
What am I doing wrong ? Can anyone help please...
Thanks
Not result = params.value, but result = value.
You have to change the line:
result = params.value
to:
result = value
At the each loop, you're basically saying that inside the params iteration, you're naming every key "key" and every value "value". So, params.value will actually look for the key value inside your params map, which is null.
Funny that you do that right with key but not with value. Probably just got distracted.
it is likely what you want to do, the groovy way (no need to loop over the keys of the map) to access "Field_10.value":"2"
result=params["Field_${attrs.id}.value"]
Alternatively, this also works because you have "Field_10":["value":"2"] in your map
result=params["Field_${attrs.id}"].value

Why am I getting this TypeError - "can't convert Symbol into Integer"?

I have an array of hashes. Each entry looks like this:
- !map:Hashie::Mash
name: Connor H Peters
id: "506253404"
I'm trying to create a second array, which contains just the id values.
["506253404"]
This is how I'm doing it
second_array = first_array.map { |hash| hash[:id] }
But I'm getting this error
TypeError in PagesController#home
can't convert Symbol into Integer
If I try
second_array = first_array.map { |hash| hash["id"] }
I get
TypeError in PagesController#home
can't convert String into Integer
What am I doing wrong? Thanks for reading.
You're using Hashie, which isn't the same as Hash from ruby core. Looking at the Hashie github repo, it seems that you can access hash keys as methods:
first_array.map { |hash| hash.id }
Try this out and see if that works--make sure that it doesn't return the object_id. As such, you may want to double-check by doing first_array.map { |hash| hash.name } to see if you're really accessing the right data.
Then, provided it's correct, you can use a proc to get the id (but with a bit more brevity):
first_array.map(&:id)
This sounds like inside the map block that hash is not actually a hashie - it's an array for some reason.
The result is that the [] method is actually an array accessor method and requires an integer. Eg. hash[0] would be valid, but not hash["id"].
You could try:
first_array.flatten.map{|hash| hash.id}
which would ensure that if you do have any nested arrays that nesting is removed.
Or perhaps
first_array.map{|hash| hash.id if hash.respond_to?(:id)}
But either way you may end up with unexpected behaviour.

Can't turn array into a string error

I have a simple call
JSON.parse(Panda.get("/videos/#{self.panda_video_id}/encodings.json"))
Which returns :
can't convert Array into String
This is because the Panda.get("/videos/#(self.panda_video_id}/encodings.json") call returns an array in the new Panda 1.0.0 gem.
I also tried :
JSON.parse(Panda.get("/videos/#{self.panda_video_id}/encodings.json").to_s)
This returns:
705: unexpected token at 'created_at2010/07/19 20:28:13 +0000video_id4df3be7b6c6888ae86f7756c77c92d8bupdated_at2010/07/19 20:28:30 +0000started_encoding_at2010/07/19 20:28:21 +0000id6e2b35ad7d1ad9c9368b473b8acd0abcextname.mp4encoding_time0encoding_progress100file_size513300height110statussuccesswidth200profile_idf1eb0fe2406d3fa3530eb7324f410789'
Question
How would you turn the call at the top so that it returns a string?
does the following work:
panda_data = Panda.get("/videos/#{self.panda_video_id}/encodings.json")
JSON.parse(panda_data.to_s)
if it doesn't what is the error output?
If panda_data is an array, panda_data.to_s is guaranteed to return a string
Not that anyone had a chance at this, but
Panda_Gem since -v=0.6 has made all Panda.[get, post, etc.] requests return a hash. So you don't need the JSON.parse anymore. Removing the JSON.parse allows it to work.

Resources