30

Given the following enumeration...

object MyEnum extends Enumeration {

  type MyEnum = Value

  val Val1 = Value("val1")
  val Val2 = Value("val2")
  val ValN = Value("valN")

  implicit val myEnumFormat = new Format[MyEnum] {
    def reads(json: JsValue) = MyEnum.withName(json.as[String].value) // doesn't compile
    def writes(myEnum: MyEnum) = JsString(myEnum.toString)
  }
}

... I need to serialize/deserialize it to/from JSON. myEnumFormat does not compile and I always get the following error message:

type mismatch;
[error]  found   : models.MyEnum.Value
[error]  required: play.api.libs.json.JsResult[models.MyEnumValue]
[error]  Note: implicit value myEnumFormat is not applicable here because it comes after the application point and it lacks an explicit result type
[error]     def reads(json: JsValue) = MyEnum.withName(json.as[JsString].value)

Am I missing something?

j3d
  • 9,492
  • 22
  • 88
  • 172

5 Answers5

34

implicit val genderReads = Reads.enumNameReads(Gender) is working fine for me. Play Scala 2.4.2

surenyonjan
  • 2,097
  • 3
  • 17
  • 26
17

Try changing it to

def reads(json: JsValue) = JsSuccess(MyEnum.withName(json.as[String].value))
Artur Nowak
  • 5,254
  • 3
  • 22
  • 32
15

Expanding on @surenyonjan's response, the following works nicely with Play Json 2.6:

object MyEnum extends Enumeration {
  type MyEnum = Value
  val e1, e2 = Value

  implicit val myEnumReads = Reads.enumNameReads(MyEnum)
  implicit val myEnumWrites = Writes.enumNameWrites
}
13

Play 2.7+

Since play-json 2.7 there is a Json.formatEnum method. Added in scope of #140

Example:

object MyEnum extends Enumeration {
  type MyEnum = Value

  val Val1 = Value("val1")
  val Val2 = Value("val2")
  val ValN = Value("valN")

  implicit val format: Format[MyEnum] = Json.formatEnum(this)
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
3

I have put together more generic and re-usable EnumerationReads, EnumerationWrites and EnumerationFormat classes and have posted them on my github page:

EnumerationCombinators.scala

Rushing
  • 126
  • 4