5

Suppose I've got a simple JSON mapped object in Crystal lang, e.g.:

class Item
  JSON.mapping(
    id: UInt32,
    name: String,
  )
end

I can parse individual objects from JSON strings easily like so:

foo = Item.from_json(%({"id":1,"name":"Foo"}))
puts "OK: foo=#{foo}"
#  => OK: foo=Item(@id=1, @name="Foo")

But how would I parse an array of Items from a JSON string? I've tried a few approaches but am not sure how to proceed, e.g.:

items_str = %([{"id":1,"name":"Foo"},{"id":2,"name":"Bar"}])
items : Array(Item) = JSON.parse(items_str)
# => Error in foo.cr:15: type must be Array(Item), not JSON::Any

Of course, I'd also like to be able to do this with a JSON pull parser, so presumably there's some mapping trick or type hint I'm missing. Ideas?

maerics
  • 151,642
  • 46
  • 269
  • 291

1 Answers1

8

Found it in this spec. So, you can use Array(Item).from_json:

items = Array(Item).from_json %([{"id":1,"name":"Foo"},{"id":2,"name":"Bar"}])

items.first.id   #=> 1
items.first.name #=> "Foo"
items.last.id    #=> 2
items.last.name  #=> "Bar"
Oleh Prypin
  • 33,184
  • 10
  • 89
  • 99
Vitalii Elenhaupt
  • 7,146
  • 3
  • 27
  • 43