17

In my controller I have the following code...

response = HTTParty.get('https://graph.facebook.com/zuck')
logger.debug(response.body.id)

I am getting a NoMethodError / undefined method `id'

If I do...

logger.debug(response.body)

It outputs as it should...

{"id":"4","name":"Mark Zuckerberg","first_name":"Mark","last_name":"Zuckerberg","link":"http:\/\/www.facebook.com\/zuck","username":"zuck","gender":"male","locale":"en_US"}

One would think it's response.body.id, but obviously that's not working. Thanks in advance!

gbdev
  • 968
  • 2
  • 11
  • 25

4 Answers4

37

Try this:

body = JSON.parse(response.body)
id = body["id"]

For this kind of thing, I'd recommend either a) using Koala or b) create a class using httparty. You can then set format: json to auto parse the returned json. See here and here

Niall Paterson
  • 3,580
  • 3
  • 29
  • 37
  • 1
    To elaborate a bit on this answer: you cannot simply treat the response of your `HTTParty.get` like it would be an ActiveRecord model. Unfortunately you will only get a hash back and not a model. – Christoph Eicke Aug 19 '13 at 18:42
  • It looks like the current version of HTTParty interprets the response from Facebook as JSON without having to do any extra coercion. – bonh May 08 '15 at 04:32
13

You can force the response to be treated as JSON using HTTParty.get like so:

response = HTTParty.get("http://itunes.apple.com/search",
    {query: {term: 'tame impala'}, format: :json})

response['results'][0]['trackName']

=> "Let It Happen"
bonh
  • 2,863
  • 2
  • 33
  • 37
9

You can use response['id'] in case that the response Content-Type is application/json or also response.parse_response to get a Hash generated from the JSON payload.

response = HTTParty.get('https://graph.facebook.com/zuck')

payload = response.parsed_response

logger.debug(payload['id'])

Note: parsed_response is a Hash, only if the response Content-Type is application/json, otherwise HTTParty will return it as a string. For enforcing a Hash, in case the response does not return application/json, you can pass the format as a parameter HTTParty.get(url, format: :json).

Pablo Cantero
  • 6,239
  • 4
  • 33
  • 44
0

HTTParty should automatically parse the content based on the content type returned. Something fishy seems to be going on with zuck's json.

pry(main)> HTTParty.get('https://graph.facebook.com/zuck')
=> "{\"id\":\"4\",\"first_name\":\"Mark\",\"gender\":\"male\",\"last_name\":\"Zuckerberg\",\"link\":\"https:\\/\\/www.facebook.com\\/zuck\",\"locale\":\"en_US\",\"name\":\"Mark Zuckerberg\",\"username\":\"zuck\"}"

But this works OK:

pry(main)> HTTParty.get('http://echo.jsontest.com/foo/bar/baz/foo')
=> {"baz"=>"foo", "foo"=>"bar"}

Don't forget to require 'httparty' if you're trying that in the console yourself.

Rimian
  • 36,864
  • 16
  • 117
  • 117