简体   繁体   中英

Play framework - pass parameter to Writes and Reads

Is there a way to pass parameter into a Writes to I will be able to control they way the JsValue is written?

This is how it looks right now:

implicit val myClassWrites = new Writes[MyClass] {
    override def writes(l: MyClass): JsValue = Json.obj("a" -> l.a, "b" -> l.b)
}

But I want to do something like this:

implicit val myClassWrites = new Writes[MyClass] (extended: Option[Boolean]) {
    override def writes(l: MyClass): JsValue = {
          extended match{
             case true => //do something
             case false => //do something else
          }
    }
}

Is there an elegant way to achieve this? or something similar?

I managed do implement this need with Reads like this(dropping the implicit):

def myClassReads(c: String) : Reads[MyClass] = (
  Reads.pure(c) and
  (JsPath \ "a").read[String] and
  (JsPath \ "b").read[String]
) (MyClass.apply _)

And then when I want to use the reads (usually in the controller when I want to validate the body of the request) I do:

request.body.validate[MyClass](MyClass.myClassReads("foo")).fold(
    errors => //
    myClass=> // do domething
)

So the Writes is still a mystery.

You can do this with implicit parameters. See code below:

case class Extended(b: Boolean)

object MyClass {

 implicit def MyClassWrites(implicit extended: Extended): Writes[MyClass] = new Writes[MyClass] {
     def writes(l: MyClass) =
          if (extended.b) JsString("foo")
          else JsString("bar")
    }
}

And then use like this

implicit var extd = Extended(true)

println(Json.toJson(myClass)) // foo

extd = Extended(false)

println(Json.toJson(myClass)) // bar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM