Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Json Writes with combinators - not all the fields of the case class are needed

I'm trying to write a custom Json serializer in play for a case class but I don't want it to serialize all the fields of the class. I'm pretty new to Scala, so that is surely the problem but this is what I tried so far:

case class Foo(a: String, b: Int, c: Double)

Now the default way of doing this, as far as I saw in the examples is:

implicit val fooWrites: Writes[Foo] = (
  (__ \ "a").write[String] and
  (__ \ "b").write[Int]
  (__ \ "c").write[Double]
) (unlift(Foo.unapply))

But what if I want to omit "c" from the Json output? I've tried this so far but it doesn't compile:

implicit val fooWritesAlt: Writes[Foo] = (
  (__ \ "a").write[String] and
  (__ \ "b").write[Int]
) (unlift({(f: Foo) => Some((f.a, f.b))}))

Any help is greatly appreciated!

like image 541
siki Avatar asked Dec 04 '13 19:12

siki


2 Answers

Instead of specifying a combinator which produces an OWrites instance, one can directly construct an OWrites just as well:

val ignore = OWrites[Any](_ => Json.obj())

implicit val fooWrites: Writes[Foo] = (
  (__ \ "a").write[String] and
  (__ \ "b").write[Int] and
  ignore
) (unlift(Foo.unapply))

This will ignore any value of the case class at that position and simply always return an empty JSON object.

like image 177
cbley Avatar answered Nov 05 '22 11:11

cbley


If you are using Playframework 2.2 (not sure about earlier versions, but it should work as well) try this:

implicit val writer = new Writes[Foo] {
  def writes(foo: Foo): JsValue = {
    Json.obj("a" -> foo.a,
             "b" -> foo.b)
  }
}
like image 23
serejja Avatar answered Nov 05 '22 11:11

serejja