15
{
  "people": [
    {
      "name": "Jack",
      "age": 15
    },
    {
      "name": "Tony",
      "age": 23
    },
    {
      "name": "Mike",
      "age": 19
    }
  ]
}

Thats a sample of the json I'm trying to parse through. I want to be able to do a foreach operation on each person and println their name and age.

I know how to handle json arrays when it's a single item or a specific numbered item. I don't know how to iterate through all items.

Can anyone help me out?

inmyth
  • 8,880
  • 4
  • 47
  • 52
Commander
  • 1,322
  • 2
  • 13
  • 29
  • Note: I am also open to using a completely different library for JSON than what is integrated with Play. But, I'd prefer not to. – Commander Mar 26 '13 at 18:15

2 Answers2

25

There are many ways to do this with the Play JSON Library. The main difference is the usage of Scala case class or not.

Given a simple json

val json = Json.parse("""{"people": [ {"name":"Jack", "age": 19}, {"name": "Tony", "age": 26} ] }""")

You can use case class and Json Macro to automatically parse the data

import play.api.libs.json._

case class People(name: String, age: Int)

implicit val peopleReader = Json.reads[People]
val peoples = (json \ "people").as[List[People]]
peoples.foreach(println)

Or without case class, manually

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val personReader: Reads[(String, Int)] = (
  (__ \ "name").read[String] and 
  (__ \ "age").read[Int]
).tupled
val peoples = (json \ "people").as[List[(String, Int)]]
peoples.foreach(println)

In other words, check the very complete documentation on this subject :) http://www.playframework.com/documentation/2.1.0/ScalaJson

Julien Lafont
  • 7,869
  • 2
  • 32
  • 52
  • My real usecase is a bit more complex than the json sample I gave. Is it possible to only read the names and completely ignore the age? Or must you always convert the entire json into a scala case class? – Commander Mar 26 '13 at 19:10
  • 1
    `(json \ "people" \\ "name")` ? – Julien Lafont Mar 26 '13 at 19:14
  • This did not work for me. It keeps saying that there is no deserializer for List[People]]. Json.reads also did not work for me. I am on Play 2.0.4 – Commander Mar 27 '13 at 15:59
  • Have you check http://www.playframework.com/documentation/2.0.4/ScalaJsonGenerics ? There are many samples. And I think the code in my last comment works with 2.0.4. – Julien Lafont Mar 27 '13 at 17:32
  • 4
    `.as[T]` is unsafe. Use `.asOpt[T]` or `.validate[T]` – Ashesh Mar 24 '15 at 14:49
4

If you don't have the object type or don't want to write a Reads, you can use .as[Array[JsValue]]

val jsValue = Json.parse(text)
val list = (jsValue \ "people").as[Array[JsValue]]

Then

list.foreach(a => println((a \ "name").as[String]))

In the older version (2.6.x) it is possible to use .as[List[JsValue]] but newer versions only support Array.

inmyth
  • 8,880
  • 4
  • 47
  • 52