Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 482
joesan Avatar asked Jan 27 '17 14:01

joesan


People also ask

What is Play JSON?

The Play JSON library. The play. api. libs. json package contains data structures for representing JSON data and utilities for converting between these data structures and other data representations.


2 Answers

Ok I figured out what has to be done!

Here it is:

  implicit object UserRoleWrites extends Writes[UserRole] {
    def writes(role: UserRole) = role match {
      case Admin => Json.toJson("Admin")
      case SuperAdmin => Json.toJson("SuperAdmin")
      case User => Json.toJson("User")
    }
  }
like image 180
joesan Avatar answered Sep 20 '22 16:09

joesan


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!

like image 22
kuba86 Avatar answered Sep 18 '22 16:09

kuba86