parsing a Json Array in play framework JsObject

json, playframework-2.0, scala

Solution

I'd argue that it's generally a good idea to move from JSON-land to native-Scala-representation-land as early as possible. If `obj` is your `JsObject`, for example, you can write this:

val subCategories = (obj \ "sub-categories").as[List[Map[String, String]]]

val names = subCategories.map(_("name"))

Or even:

case class Category(name: String, subs: List[String])

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

implicit val categoryReader = (
  (__ \ "web-category").read[String] and
  (__ \ "sub-categories").read[List[Map[String, String]]].map(_.map(_("name")))
)(Category)

And then:

obj.as[Category]

This latter approach makes error handling even cleaner (e.g. you can just replace `as` with `asOpt` at this top level) and composes nicely with other `Reads` type class instances—if you have a `JsArray` of these objects, for example, you can just write `array.as[List[Category]]` and get what you expect.

Problem

I have the following Json: ``` { "web-category" : "macaroons", "sub-categories" : [ { "name" : "pink" }, { "name" : "blue" }, { "name" : "green" } ] } ``` I have got it in Play as a JsObject. So I can now successfully do the following: ``` //(o is the JsObject) val webCat:Option[String] = (o \ "web-category").asOpt[String] println(webCat.toString) >> Some(macaroons) ``` So far, so good. But how do I access the array Json objects? I have this... ``` val subCats:Option[JsArray] = (o \ "sub-categories").asOpt[JsArray] println(subCats.toString) >> Some([{"name" : "blue"},{"name" : "green"},{"name" : "pink"}]) ``` but what I need is to take the JsArray and get a List of all the names something like this: ``` List("blue", "green", "pink") ``` Don't know how to access the JsArray thusly. my thanks for your help in this.

Original source