play framework json lookup inside array

46 views Asked by At

I have simple json:

{
  "name": "John",
  "placesVisited": [
    {
      "name": "Paris",
      "data": {
        "weather": "warm",
        "date": "31/01/22"
      }
    },
    {
      "name": "New York",
      "data": [
        {
          "weather": "warm",
          "date": "31/01/21"
        },
        {
          "weather": "cold",
          "date": "28/01/21"
        }
      ]
    }
  ]
}

as you can see in this json there is placesVisited field, and if name is "New York" the "data" field is a List, and if the name is "Paris" its an object.

what I want to do is to pull the placesVisited object where "name": "New York" and then I will parse it to a case class I have, I can't use this case class for both objects in placesVisited cause they have diff types for the same name.

so what I thought is to do something like:

(myJson \ "placesVisited") and here I need to add something that will give me element where name is "New York", how can I do that?

my result should be this:

{
  "name": "New York",
  "data": [
    {
      "weather": "warm",
      "date": "31/01/21"
    },
    {
      "weather": "cold",
      "date": "28/01/21"
    }
  ]
}

something like this maybe can happen but its horrible haha:

(Json.parse(myjson) \ "placesVisited").as[List[JsObject]].find(item => {
  item.value.get("name").toString.contains("New York")
}).getOrElse(throw Exception("could not find New York element")).as[NewYorkModel]
1

There are 1 answers

0
Gaël J On

item.value.get("name").toString can slightly be simplified to (item \ "name").as[String] but otherwise there's not much to improve.

Another option is to use a case class Place(name: String, data: JsValue) and do it like this:

(Json.parse(myjson) \ "placesVisited")
  .as[List[Place]]
  .find(_.name == "New York")