1
votes

Given the following case class and JSON

case class Profile(name: String, `type`: String, value: String, sort: Long = 0)

val json_string = """[
  {"name": "Birthday", "type": "DateTime", "value": "12/25/1990"},
  {"name": "Fullname", "type": "String", "value": "Birthday Boy"}
]"""

The following call:

val profiles = Json.parse(json_string).as[Seq[Profile]]

Results in the exception:

JsResultException(errors:List(((0)/sort,List(ValidationError(error.path.missing,WrappedArray()))), ((1)/sort,List(ValidationError(error.path.missing,WrappedArray())))))

If I add the a sort key to my JSON string the deserialization works as expected. Why doesn't the default value for sort in the case class "kick in" and allow the deserialization?

I'm using JsMacroInception to define the reads/writes

   val implicit profileReader = Json[Profile].reads
   val implicit profileWriter = Json[Profile].writes

Can I do something with the reader to support the optional constructor parameter?

2
In Spray-json you would make the type an Option, e.g. Option[Long].AmigoNico
I could make it an option, but I'd prefer to have a default value if that's possible.Jason

2 Answers

1
votes

The JSON reads macro won't take default constructor values into account when generating Reads[Profile]. So if you want to still use the macro, your only choice is to make sort an Option[Long]. If you want to provide a default value, then I suggest you go with JSON combinators:

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val reads: Reads[Profile] = (
    (__ \ "name").read[String] and 
    (__ \ "type").read[String] and 
    (__ \ "value").read[String] and 
    (__ \ "sort").read[Long].orElse(Reads.pure(0L))
)(Profile.apply _)

If sort isn't found within a JSON object, orElse will be applied, which in this case I use Reads.pure to provide a fixed default value.

1
votes

You need to make sort an Option but then null or non included value would be none . If that does not work you would then have to write your own reads to set default value in case of null / missing sort