parsing a Json Array in play framework JsObject

30,078

Solution 1

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.

Solution 2

What Peter said, or:

(o \ "sub-categories" \\ "name").map(_.as[String]).toList

Solution 3

Something like this:

subCats.map( jsarray => jsarray.value.map(jsvalue => (jsvalue \ "name").as[String]).toList)

This will normally return a Option[List[String]]

Share:
30,078
Zuriar
Author by

Zuriar

Updated on February 27, 2020

Comments

  • Zuriar
    Zuriar about 4 years

    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.

  • Zuriar
    Zuriar about 10 years
    Edit no I don't, my bad. I used 'sub-category' in actual fact, not 'sub-categories. Thanks for your help!