0

I have a JSArray like below from server (I cannot change as it belongs to others):

[ {"name": "US", "id": 0, "translations" : {"name: {"es": "Estados unidos", "fr": "Etats-unis"}}},
{"name": "UK", "id": 1, "translations" : {"name: {"es": "Estados Kdda", "fr": "dsfjas"}}},
...
]

I need to extract all the name like US, UK but not name in translations and also id.

I tried several ways and it always have problem. Below are what I tried.

I first tried

case class Country(name: String, id:String) 

implicit object CountryReads extends Reads[Country] {  
def reads(json: JsValue) = Country(
                        (json \ "name"),
                        (json \ "id")
                    )
}

val countries = Json.parse(result) match {  //here result is Json String
           case JsArray(Seq(t)) => Some(t.as[Seq[Country]])
           case _ => None
}

But I get compiling error as below:

[error] C:\git9\hss\app\models\LivingSocial.scala:80: type mismatch;
[error]  found   : play.api.libs.json.JsValue
[error]  required: play.api.libs.json.JsResult[MyCountry]
[error]                        def reads(json: JsValue) =    (json \ "currencyCode")
[error]                                                            ^
[error] one error found
[error] (compile:compile) Compilation failed

then I tried:

val jResult = Json.parse(result)
(jResult \\ "name").foreach { name => 
   println(name.as[String])
}

I get error in println() as "\" will recursively pull names under translation also.

Any good way to do it?

1
  • Your compiler error references a currencyCode field which isn't in your code. Are you sure that's everything? Commented Aug 14, 2014 at 22:11

2 Answers 2

2
case class Country(name: String, id: Int, translations: Map[String, Map[String, String]])

object Country {

  implicit val format = Json.format[Country]

}

val js = Json.parse(yourString)

val names: JsResult[Seq[String]] = js.validate[Seq[Country]].map { countries => countries.map(_.name) }

At that point you can deal with the JsResult since you'll need error handling in case the JSON doesn't conform to your expectations.

Sign up to request clarification or add additional context in comments.

Comments

0

You can change your read to look like this :

implicit val CountryReads: Reads[Country] = (
        (JsPath \ "name").read[String] and
          (JsPath \ "name").read[String]
        )(Country.apply _)

this is a correct way to create a reader according to play documentation

1 Comment

There is no one right way to create a reader according to the pre-canned Reads definitions in the play source - github.com/playframework/playframework/blob/master/framework/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.