Reputation: 307
I am trying to build a quick hack that "likes" all the recent photos on instagram of a particular tag.
I have authenticated and used the JSON gem to turn the JSON from the API into a Ruby Hash like this:
def get_content (tag_name)
uri = URI.parse("https://api.instagram.com/v1/tags/#{tag_name}/media/recent? access_token=#{@api_token}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
json_output = http.request(request)
@tags = JSON.parse(json_output.body)
end
This outputs a hash with arrays as keys nested like the original JSON ( ex. http://instagr.am/developer/endpoints/tags/
)
I am trying to iterate over and retrieve all the "id"s of the photos.
However when I use each method:
@tags.each do |item|
puts item["id"]
end
I get an error:
instagram.rb:23:in `[]': can't convert String into Integer (TypeError)
from instagram.rb:23:in `block in like_content'
from instagram.rb:22:in `each'
from instagram.rb:22:in `like_content'
from instagram.rb:42:in `<main>'
Upvotes: 3
Views: 8628
Reputation: 106027
instagram.rb:23:in `[]': can't convert String into Integer (TypeError)
You're getting this error because in puts item["id"]
, item
is an Array, not a Hash, so Ruby tries to convert what you put between []
into an integer index, but it can't because it's a string ("id"
).
This arises from the fact that json_output.body
is a Hash. Take a second look at the example JSON response in the documentation:
{ "data" : [
{ "type" : "image",
// ...
"id" : "22699663",
"location" : null
},
// ...
]
}
This whole structure becomes a single Hash with one key, "data"
, so when you call @tags.each
you're actually calling Hash#each
, and since "data"
's value is an Array when you call item["id"]
you're calling Array#[]
with the wrong kind of parameter.
Long story short, what you actually want to do is probably this:
@tags = JSON.parse( json_output.body )[ "data" ]
..then @tags
will be the Array you want instead of a Hash and you can iterate over its members like you wanted:
@tags.each do |item|
puts item["id"]
end
Upvotes: 15