16

Trying to parse some JSON, byt why is text empty?

Desired output:

text should return Hello world\n\nApple, Harbor\n\nBanana, Kitchen\n\nMango, Bedroom

text = "Hello world"

json = '{"fruits": [{"name": "Apple", "location": "Harbor"}, {"name": "Banana", "location": "Kitchen"}, {"name": "Mango", "location": "Bedroom"}]}'
fruits = JSON.parse(json)

def format_fruits(fruits)
  fruits.each do |fruit|
    puts "\n\n#{ fruit[0]['name'] }, #{ fruit[0]['location'] }"
  end.to_sentence
end

text += format_fruits(fruits)
text

Current output:

TypeError: no implicit conversion of Hash into String
        from (irb):5:in `+'
        from (irb):5
        from /home/mark/.gem/ruby/2.1.1/gems/railties-4.1.7/lib/rails/commands/console.rb:90:in `start'
        from /home/mark/.gem/ruby/2.1.1/gems/railties-4.1.7/lib/rails/commands/console.rb:9:in `start'
        from /home/mark/.gem/ruby/2.1.1/gems/railties-4.1.7/lib/rails/commands/commands_tasks.rb:69:in `console'
        from /home/mark/.gem/ruby/2.1.1/gems/railties-4.1.7/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
        from /home/mark/.gem/ruby/2.1.1/gems/railties-4.1.7/lib/rails/commands.rb:17:in `<top (required)>'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:247:in `require'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:247:in `block in require'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:232:in `load_dependency'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:247:in `require'
        from /home/mark/myapp/bin/rails:8:in `<top (required)>'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:241:in `load'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:241:in `block in load'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:232:in `load_dependency'
        from /home/mark/.gem/ruby/2.1.1/gems/activesupport-4.1.7/lib/active_support/dependencies.rb:241:in `load'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/commands/rails.rb:6:in `call'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/command_wrapper.rb:38:in `call'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application.rb:180:in `block in serve'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application.rb:153:in `fork'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application.rb:153:in `serve'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application.rb:128:in `block in run'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application.rb:122:in `loop'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application.rb:122:in `run'
        from /home/mark/.gem/ruby/2.1.1/gems/spring-1.1.3/lib/spring/application/boot.rb:18:in `<top (required)>'
        from /home/mark/.rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /home/mark/.rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from -e:1:in `<main>'irb(main):006:0> text
=> "Hello world"
irb(main):007:0>
3
  • 1
    I'm not familiar with to_sentence. Can you explain that? Commented Dec 9, 2014 at 5:52
  • NoMethodError: undefined method to_sentence' for #<Hash:0x7f571f746e18> are you using any gem? Commented Dec 9, 2014 at 5:55
  • 3
    to_sentence is ActiveSupport method available in Rails. Also, it's callable on Array, not on Hash. Commented Dec 9, 2014 at 5:57

2 Answers 2

12

The error is a result of calling Array#to_sentence on a hash.

More specifically, fruits is a Hash, and calling fruits.each { ... } returns the original fruits Hash unchanged. Thus calling fruits.to_sentence causes the observed error.

Here's a fixed-up version with comments denoting the changes:

require 'json'

text = "Hello world"

json = '{"fruits": [{"name": "Apple", "location": "Harbor"}, {"name": "Banana", "location": "Kitchen"}, {"name": "Mango", "location": "Bedroom"}]}'
fruits = JSON.parse(json)['fruits'] # append ['fruits']

def format_fruits(fruits)
  fruits.map do |fruit| # change each -> map
    "\n\n#{ fruit['name'] }, #{ fruit['location'] }" # delete puts, [0]
  end.join # change to_sentence -> join
end

text += format_fruits(fruits)
puts text

Output:

Hello world

Apple, Harbor

Banana, Kitchen

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

1 Comment

It would be nice to have an accompanying explanation as to what the issue actually was.
4

In-case your json always contains "fruits" key, you can achieve this quite easily. Here:

fruits = JSON.parse(json)
#=> {"fruits"=>[{"name"=>"Apple", "location"=>"Harbor"}, {"name"=>"Banana", "location"=>"Kitchen"}, {"name"=>"Mango", "location"=>"Bedroom"}]}

fruits["fruits"].each { |hash|
  puts "\n\n#{hash['name']}, #{hash['location']}"
}

Another way to do this without using fruits key:

fruits.values.first.each { |hash|
  puts "\n\n#{hash['name']}, #{hash['location']}"
}

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.