Problems with parsing JSON POST body

3,050 views
Skip to first unread message

jbrennan

unread,
Jul 22, 2010, 9:33:29 PM7/22/10
to sinatrarb
I'm quite amatuerish with Ruby and Sinatra so please stay with me.
I've got a very simple Sinatra app and I'm POSTing a JSON object from
my client app (iPhone). Here's what my route looks like.

post '/changes' do
puts "Got a hit"
body = JSON.parse(request.body.read.to_s) # now contains a valid
json object of the POST body
local_changes_array = body["LocalChangesArray"] #
"LocalChangesArray" is a valid key in my object
end

However, when I post the data to the server, I get the following error
on the last line:

> NoMethodError: undefined method `bytesize' for #<Hash:0x102023ca0>

followed by a lengthy stack trace.

I'm not sure why "body" (which is my parsed JSON hash) is giving me
that error when I try to access it with a key. I've checked (via puts)
that the json object is arriving as expected.

I'm at a complete loss, any help would be immensely appreciated!
Jason.

nouse

unread,
Jul 22, 2010, 11:19:58 PM7/22/10
to sinatrarb

On Jul 23, 9:33 am, jbrennan <i.jasonbren...@gmail.com> wrote:

>
> I'm not sure why "body" (which is my parsed JSON hash) is giving me
> that error when I try to access it with a key. I've checked (via puts)
> that the json object is arriving as expected.
>
> I'm at a complete loss, any help would be immensely appreciated!
> Jason.

That is exactly the reason. In line 84 of sinatra/base.rb defines the
body method, it will set response's body.

# Set or retrieve the response body. When a block is given,
# evaluation is deferred until the body is read with #each.
def body(value=nil, &block)
if block_given?
def block.each ; yield call ; end
response.body = block
else
response.body = value
end
end


jbrennan

unread,
Jul 23, 2010, 12:19:40 AM7/23/10
to sinatrarb
I should amend my original question. I've since changed the name of my
variable, but I cannot seem to parse the request body to a json
object. So my code looks like so:

post '/changes' do
puts "Got a hit"
bodyJSON = JSON.parse(request.body.read.to_s) # now contains a
valid
json object of the POST body
local_changes_array = bodyJSON["LocalChangesArray"] #
"LocalChangesArray" is a valid key in my object
end

Yet I still get this error: NoMethodError: undefined method `bytesize'
for #<Hash:0x1021f33a0>

Ideas? Am I somehow not accessing the body of my POST properly? I've
set the content-type of my POST request to "application/json", but I
have a feeling like I'm just not getting the post body properly. Could
it have something to do with the json quotes not being escaped or
something?

Jason.

Patrick Bacon

unread,
Jul 23, 2010, 6:41:11 AM7/23/10
to sina...@googlegroups.com
Try this:

JSON.parse(request.env["rack.input"].read)

- Patrick

> --
> You received this message because you are subscribed to the Google Groups "sinatrarb" group.
> To post to this group, send email to sina...@googlegroups.com.
> To unsubscribe from this group, send email to sinatrarb+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sinatrarb?hl=en.
>
>

Damian Janowski

unread,
Jul 23, 2010, 7:27:14 AM7/23/10
to sina...@googlegroups.com
On Fri, Jul 23, 2010 at 1:19 AM, jbrennan <i.jason...@gmail.com> wrote:
> I should amend my original question. I've since changed the name of my
> variable, but I cannot seem to parse the request body to a json
> object. So my code looks like so:
>
> post '/changes' do
>  puts "Got a hit"
>  bodyJSON = JSON.parse(request.body.read.to_s) # now contains a
> valid
> json object of the POST body
>  local_changes_array = bodyJSON["LocalChangesArray"] #
> "LocalChangesArray" is a valid key in my object
> end
>
> Yet I still get this error: NoMethodError: undefined method `bytesize'
> for #<Hash:0x1021f33a0>
>
> Ideas? Am I somehow not accessing the body of my POST properly? I've
> set the content-type of my POST request to "application/json", but I
> have a feeling like I'm just not getting the post body properly. Could
> it have something to do with the json quotes not being escaped or
> something?

The return value of the block is what Sinatra will send back as the
response body.

Try:

post "/changes" do
# ...
local_changes_array = bodyJSON["LocalChangesArray"]
local_changes_array.to_json
end

Konstantin Haase

unread,
Jul 23, 2010, 7:29:33 AM7/23/10
to sina...@googlegroups.com

On Jul 23, 2010, at 12:41 , Patrick Bacon wrote:

> Try this:
>
> JSON.parse(request.env["rack.input"].read)
>
> - Patrick

You should do a request.env["rack.input"].rewind first.

Konstantin

jbrennan

unread,
Jul 27, 2010, 11:57:18 PM7/27/10
to sinatrarb
Got it working.

Thanks all!!
Reply all
Reply to author
Forward
0 new messages