Reputation:
I have this problem, where I keep on getting
TypeError: can't convert String into Integer
This is where I'm going through this @data object.
here is the @data object
@data = HTTParty.get("")
{
"body"=>{
"predictions"=>{
"direction"=>{
"prediction"=>[
{
"epochTime"=>"1362931090892",
},
{
"epochTime"=>"1362931747892",
},
{
"epochTime"=>"1362932467892",
},
{
"epochTime"=>"1362933187892",
},
{
"epochTime"=>"1362933847892",
}
],
"title"=>"xxxx"
},
"a"=>"xx",
"b"=>"x"
},
"name"=>"some"
}
}
and my code to go through above has been
<% if @data["body"]["predictions"].present? %>
<% @data["body"]["predictions"].each do |p| %>
<%p["direction"].each do |d|%>
<% d["prediction"].each do |k|%>
<h4><%= k["epchoTime.."] %> </h4>
<%end%>
<%end%>
<%end%>
<%end%>
I have no idea how to go through this, I assume this is due to the fact I should access stuff like I do in C++ with name[integer] value, but I would like to use ["name"]. How can I make my code work ?
Thanks for your precious time and consideration.
Upvotes: 0
Views: 313
Reputation: 160631
Here's an example, using Nokogiri, of parsing the raw XML:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<body>
<predictions>
<direction>
<prediction>
<epochTime>1362931090892</epochTime>
<epochTime>1362931747892</epochTime>
<epochTime>1362932467892</epochTime>
<epochTime>1362933187892</epochTime>
<epochTime>1362933847892</epochTime>
</prediction>
<title">xxxx</title>
<a>"xx"</a>
<b>"x"</b>
<name>"some"</name>
</direction>
</predictions>
</body>
EOT
epoch_times = doc.search('epochTime').map(&:text)
Which returns an array of epochTime
values:
[
[0] "1362931090892",
[1] "1362931747892",
[2] "1362932467892",
[3] "1362933187892",
[4] "1362933847892"
]
Sometimes we need to loop through all prediction
blocks containing the epochTime
blocks. This will do it:
epoch_times = doc.search('prediction').map{ |predict|
predict.search('epochTime').map(&:text)
}
[
[0] [
[0] "1362931090892",
[1] "1362931747892",
[2] "1362932467892",
[3] "1362933187892",
[4] "1362933847892"
]
]
Sometimes you need to find a particular node and grab all the elements of a certain type inside it:
doc = Nokogiri::XML(<<EOT)
<body>
<predictions>
<direction>
<prediction id="1">
<epochTime>1362931090892</epochTime>
<epochTime>1362931747892</epochTime>
<epochTime>1362932467892</epochTime>
<epochTime>1362933187892</epochTime>
<epochTime>1362933847892</epochTime>
</prediction>
<title">xxxx</title>
<a>"xx"</a>
<b>"x"</b>
<name>"some"</name>
</direction>
</predictions>
</body>
EOT
epoch_times = doc.search('prediction[id="1"]').map{ |predict| predict.search('epochTime').map(&:text) }
[
[0] [
[0] "1362931090892",
[1] "1362931747892",
[2] "1362932467892",
[3] "1362933187892",
[4] "1362933847892"
]
]
Upvotes: 1
Reputation:
The whole hash things was getting out of hand as I had constantly detect each one's present and loop through it, so As Tin man suggested, I used XML 'nokogiri' and then used .css method to detect if it existed and looped through it, since original response was in xml.
@doc.css('predictions').each do |predictions_node|
predictions_node.css('direction').each do |direction_node|
direction_node.css('prediction').each do |prediction|
// stuff here
Thanks for your time and consideration.
Upvotes: 0
Reputation: 8132
Looks like you are ignoring the keys which don't have nested values say title
and a
, b
.
"title"=>"xxxx"
},
"a"=>"xx",
"b"=>"x"
},
Your final code should look like
if @data["body"]["predictions"].present?
@data["body"]["predictions"].each do |p|
p.each do |d|
if d.kind_of? Hash
d.each do |k|
if k.kind_of? Array
k.each do |x|
if x.kind_of? Array
x.each do |y|
if y.kind_of? Hash
puts y["epochTime"]
end
end
end
end
end
end
end
end
end
end
The above code is ugly but you are C++ programmmer , you might like it :P
Upvotes: 0
Reputation: 998
the Tin Man has a good point about keeping this logic outside the view, and should be a work of a model. Here is a cleaner view though.
<% @data['body']['predictions']['direction']['prediction'].each do |x| %>
<% x.each do |k, v| %>
<h4><%= v %></h4>
<% end %>
<% end %>
Upvotes: 0