In play 2.1 reads are used to marshall Json to objects. But how can I do this when the case class has only one field. The ideom that works for more fields does not work, as with one field 'and' is not used. Thus I do not get a FunctionBuilder.
The following code gives me a type mismatch. How can I fix this?
case class Data(stamm: Seq[String])
implicit val dataReads = (
(__ \ "stamm").read(Reads.list[String])
)(Data)
Json combinators doesn't work for single field case class.
Pascal (writer of this API) has explained this situation here
https://groups.google.com/forum/?fromgroups=#!starred/play-framework/hGrveOkbJ6U
There are some workarounds which works, like this one:
case class A(value: List[Int])
val areads = (__ \ 'value).read[List[Int]].map{ l => A(l) } // covariant map
As Julien answered, you can read single field case classes using this:
case class Person(name: String)
val personReads: Reads[Person] =
(__ \ "name").read[String].map { name => Person(name) }
Just a complement, if you want to write:
val personWrites: Writes[Person] =
(__ \ "name").write[String].contramap { (person: Person) => person.name }
Or format (read and write):
val personFormat: Format[Person] =
(__ \ "name").format[String].inmap(name => Person(name), (person: Person) => person.name)
For write and format you have to import this:
import play.api.libs.functional.syntax._
Based on @yokomizor's answer, I found the simplest solution to create a Formatter
to be
case class Person(name: String)
val personFormatter: Format[Person] =
(__ \ "full_name").format[String].inmap(Person.apply, unlift(Person.unapply))
Even simpler solution than the accepted one:
case class A(value: String)
val reads = (__ \ "key").read[String].map(A.apply)