1
votes

I have the following class structure in Play for Scala:

sealed trait Father
final case class Child1 (name: String, descrip: String) extends Father
final case class Child2 (age: Int, price: Int) extends Father

case class MyClass (someValue: Int, father: Father)

Now, I need to define the implicit JSON functions for MyClass:

  implicit val myClassWrite : Writes[MyClass] = (
     (JsPath \ "some").write[Int] and
     (JsPath \ "father").write[Father]
  ) (unlift(MyClass.unapply)) 

What I get is:

No Json serializer found for type Father. Try to implement an implicit Writes or Format for this type.

The thing is that there's no way to write a Writes JSON function for Father as it's a trait with no attributes. I can only write JSON functions for Child1 and Child2, but I still get the error. My intent is for Play to insert the JSON of Child1 or Child2 depending on the instance type. Is this something Play can do?

1
Play JSON can generate writer for the sealed trait directly. - cchantep

1 Answers

2
votes
implicit val c1 = Json.format[Child1]
implicit val c2 = Json.format[Child2]

implicit val fatherWrites = new Writes[Father] {
  override def writes(o: Father) = o match {
    case x: Child1 => c1.writes(x)
    case x: Child2 => c2.writes(x)
  }
}

// test

val father : Father = Child1("aa","aaa")
Json.toJson(father).toString() // {"name":"aa","descrip":"aaa"}