2

I know I am missing something probably very obvious. I am trying to iterate over a JSON array in my Rails5 view. I tried several things but can't seem to get the proper items to render. The below code renders {"name"=>"Large Plaque", "price"=>"2500"} {"name"=>"Small Plaque", "price"=>"1500"} to my view.

config/plaque_data.json

{
  "products": [
    {
      "name": "Large Plaque",
      "price": "2500"
    },
    {
      "name": "Small Plaque",
      "price": "1500"
    }
  ]
}

controllers/plaqueorders_controller.rb

...
def new
 @plaqy = JSON.load File.read('config/plaque_data.json')
end
...

views/plaqueorders/new.html.erb

...
<% @plaqy['products'].each do |k, v| { name: k, price: v } %>
 <%= k %>
<% end %>
...
4
  • have you tried to see the output of JSON.load(File.read('config/plaque_data.json'))? (in your irb console for example) Commented Oct 11, 2017 at 16:39
  • @MrYoshiji this is what is printed in console => {"products"=>[{"name"=>"Large Plaque", "price"=>"2500"}, {"name"=>"Small Plaque", "price"=>"1500"}]} Commented Oct 11, 2017 at 16:40
  • 1
    You really should specify the full path to that file, like Rails.root.join('config/plaque_data.json'). Commented Oct 11, 2017 at 16:52
  • 1
    Also, if the plaque_data.json file is not meant to change, you might want to load it at the server start and cache it instead of reading it every time this action is hit Commented Oct 11, 2017 at 17:23

2 Answers 2

2

Since 'k' is a hash, you need to access k['name'] and k['price'] to extract price and name.

Also when you use .each on an array, you normally only declare one block argument (You have two, k and v ).

You normally write 2 block arguments for Hashes (and lots of other Enumerable methods), which is possibly what you thought you were iterating over, but

@plaqy['products']

is an array

Sign up to request clarification or add additional context in comments.

Comments

1

Just to expand on the above answer, in your view you are iterating over an array, but treating it like a hash. So you might want to change your view to something like:

views/plaqueorders/new.html.erb

...
<% @plaqy['products'].each do |product|%>
 Name: <%= product['name'] %>
 Price: $<%= product['price'] %>
<% end %>
...

Obviously the block will change based on how you want to render each product, but something like that will work.

If you want to loop over the hashes because you don't know what the shape is (strange but okay), you'd want something like

...
<% @plaqy['products'].each do |product|%>
 <% product.each do |key, value| %>
   <%= key %>: <%= value %>
 <% end %>
<% end %>
...

Naming the variables of an each loop k, v is generally reserved for hashes. But in your code, the k wasn't the key of the hash but rather each individual product.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.