Search code examples
scalaplayframeworkplay-json

Play Framework JSON Format for Case Objects


I have a set of case objects that inherits from a trait as below:

  sealed trait UserRole
  case object SuperAdmin extends UserRole
  case object Admin extends UserRole
  case object User extends UserRole

I want to serialize this as JSON and I just used the Format mechanism:

implicit val userRoleFormat: Format[UserRole] = Json.format[UserRole]

But unfortunately, the compiler is not happy and it says:

No unapply or unapplySeq function found

What is wrong in my case objects?


Solution

  • Another option is to override def toString like this:

    File: Status.scala

        package models
    
        trait Status
        case object Active extends Status {
          override def toString: String = this.productPrefix
        }
        case object InActive extends Status {
          override def toString: String = this.productPrefix
        }
    

    this.productPrefix will give you case object name

    File: Answer.scala

    package models
    
    import play.api.libs.json._
    
    case class Answer(
        id: Int,
        label: String,
        status: Status
    ) {
      implicit val answerWrites = new Writes[Answer] {
        def writes(answer: Answer): JsObject = Json.obj(
          "id" -> answer.id,
          "label" -> answer.label,
          "status" -> answer.status.toString
        )
      }
      def toJson = {
        Json.toJson(this)
      }
    }
    

    File: Controller.scala

    import models._
    val jsonAnswer = Answer(1, "Blue", Active).toJson
    println(jsonAnswer)
    

    you get:

    {"id":1,"label":"Blue","status":"Active"}
    

    Hope this helps!