Search code examples
jsonscalaplay-json

How could I properly work with Scala Play Read?


According to this documentation (official):

https://www.playframework.com/documentation/2.8.x/ScalaJsonCombinators

I have to create a case class, after that I have to create a JsonReader:

val nameReads: Reads[String] = (JsPath \ "name").read[String]

then

val nameResult: JsResult[String] = json.validate[String](nameReads)

So, the result would be into nameResult and it was expecting that data was accessible like this:

println(nameResult.name)

Unfortunately, it doesn't work. It doesn't print results or return them. First of all I work with Future and read JSON from web

implicit val context = scala.concurrent.ExecutionContext.Implicits.global

val userReads: Reads[User] = (
  (JsPath  \ "id").read[Int] and
  (JsPath  \ "login").read[String]
)

val futureResult = wc.url(path).get().map {
  response =>
    response.json.validate[User](userReads)
}

futureResult.map(r => println(r.id, r.login))

But! This code works, but it isn't in documentation.

implicit val context = scala.concurrent.ExecutionContext.Implicits.global

val userReads: Reads[User] = (
  (JsPath  \ "id").read[Int] and
  (JsPath  \ "login").read[String]
)

val futureResult = wc.url(path).get().map {
  response =>
    UserTest(
      (response.json \ "id").as[String],
      (response.json \ "login").as[String]
    )
}

futureResult.map(r => println(r.id, r.login))

Does somebody know why code into documentation doesn't work? What is wrong with it? Could I use my code?


Solution

  • Calling validate[User] doesn't return a User but a JsResult[User]. This is because the JSON data might be invalid and your code needs to handle this case. There is an example in the documentation that you have linked to:

    json.validate[Place] match {
      case JsSuccess(place, _) => {
        val _: Place = place
        // do something with place
      }
      case e: JsError => {
        // error handling flow
      }
    }