0

I am trying to parse json object with a list inside let's say

{
   "foo": 12,
   "bar": [ 12, null, null, 32 ]
}

In our project we are referring to the scala play documentation and trying to declare a simple json read parser like Json.reads[MyObject]

and case class looks like:

case class MyObject(
    foo: Int,
    bar: List[Option[Int]]
 )

but compiler complains about it:

Error:(93, 42) No instance of play.api.libs.json.Reads is available for scala.collection.immutable.List[scala.Option[scala.Int]] in the implicit scope (Hint: if declared in the same file, make sure it's declared before) implicit val readMyObject = Json.reads[MyObject]

Anyone knows any workarounds?

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

Evilguy
  • 306
  • 2
  • 14

2 Answers2

0

Add optionReads method to the object companion.

val str = """{
   "foo": 12,
   "bar": [ 12, null, null, 32 ]
}"""

case class MyObject(foo: Int, bar: List[Option[Int]])

object MyObject {

  implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]

  implicit val reads = Json.reads[MyObject]

}

val json = Json.parse(str)

val obj = Json.fromJson[MyObject](json)

println(obj)
// JsSuccess(MyObject(12,List(Some(12), None, None, Some(32))),)
Sebastian Celestino
  • 1,388
  • 8
  • 15
  • When I am adding `implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]` I receive compilation error :( `Error:(11, 73) type mismatch; found : play.api.libs.json.JsValue => play.api.libs.json.JsResult[Option[T]] required: play.api.libs.json.Reads[Option[T]] implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]` – Evilguy Sep 28 '18 at 08:51
  • Could there be a problem with scala version I am using? `2.11.12` – Evilguy Sep 28 '18 at 09:09
  • Maybe, I am using 2.12.6. I'm going to check with 2.11.12 version. – Sebastian Celestino Sep 28 '18 at 13:50
0

I am not sure why

  implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]

was causing compilation error:

Error:(11, 73) type mismatch; found : play.api.libs.json.JsValue => play.api.libs.json.JsResult[Option[T]] required: play.api.libs.json.Reads[Option[T]] implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]

But I have solved it by adding

    implicit def optionFormat[T: Format]: Format[Option[T]] =
      new Format[Option[T]] {
        override def reads(json: JsValue): JsResult[Option[T]] =
          json.validateOpt[T]
    }

from post No Json formatter for Option[String]?

Evilguy
  • 306
  • 2
  • 14