David Portabella
David Portabella

Reputation: 12720

No Json deserializer found for type List Option

How can I use the play json OFormat macro to get a list of option?

val text = """[{"name": "John", "age": 30}, null, {"name": "Steve", "age": 34}]"""
import play.api.libs.json.Json
case class Person(name: String, age: Int)
implicit val personFormat = Json.format[Person]
val data = Json.parse(text).validate[List[Option[Person]]]

// Error: No Json deserializer found for type List[Option[Person]]. Try to implement an implicit Reads or Format for this type.

I am doing as follows, as a workaround:

val data = Json.parse(text).as[Array[JsValue]].toList.map {
  case JsNull => None
  case x => Some(x.validate[Person].get)
}
println(data)

// List(Some(Person(John,30)), None, Some(Person(Steve,34)))

How do I achieve the same without this workaround, using only the OFormat macro?

Upvotes: 1

Views: 2221

Answers (1)

Evgeny
Evgeny

Reputation: 1770

Not sure that it is possible directly, but could be done so for example (used this answer):

val text = """[{"name": "John", "age": 30}, null, {"name": "Steve", "age": 34}]"""

import play.api.libs.json._

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

  override def writes(o: Option[T]) = o match {
    case Some(t) ⇒ implicitly[Writes[T]].writes(t)
    case None ⇒ JsNull
  }
}

case class Person(name: String, age: Int)

implicit val personFormat= {
  implicit val f = Json.format[Person]
  implicitly[Format[Option[Person]]]
}


val data = Json.parse(text).validate[List[Option[Person]]] // JsSuccess(List(Some(Person(John,30)), None, Some(Person(Steve,34))),)
Json.toJson(data.get) // [{"name":"John","age":30},null,{"name":"Steve","age":34}]

it just cannot translate by its own Reads[Person] -> Reads[Option[Person]] -> Reads[List[Option[Person]]]. I do help to get Reads[Option[Person]] with helper general method. Probably, analogue method is available in play lib..

Upvotes: 1

Related Questions