jsonplayframework-2.0playframework-2.4

playframework - Best way to trim a json values


I am trying to figure out the best and elegant way to tim values on an in coming json.

So for example I have the following json:

{
  "firstName": "   foo",
  "lastName": "bar    "
}

With the following definitions:

case class Someone(firstName:String, lastName: String)
object Someone{
  implicit val someoneReads: Reads[Someone] = (
      (JsPath \ "firstName").read[String] and
      (JsPath \ "lastName").read[String]
    )(Someone.apply _)
}

Is there a way to trim the json while reading it? or I need to write a transformer for that? and if I do, how to write it so it will be generic to trip every json I will provide?

Thanks!


Solution

  • Use map(_.trim) for read[String] for trim string (universal solution)

    implicit val someoneReads: Reads[Someone] = (
        (JsPath \ "firstName").read[String].map(_.trim) and
          (JsPath \ "lastName").read[String].map(_.trim)
        )(Someone.apply _)
    

    You can implement own Reads[String] with trimmed string also

    def trimmedString(path: JsPath): Reads[String] = Reads.at[String](path).map(_.trim)
    
    implicit val someoneReads: Reads[Someone] = (
      trimmedString(JsPath \ "firstName") and trimmedString(JsPath \ "lastName")    
      )(Someone.apply _)
    

    For a more familiar view of code you may implement implicit conversion

    import scala.language.implicitConversions
    
    class JsPathHelper(val path: JsPath) {
      def trimmedString: Reads[String] = Reads.at[String](path).map(_.trim)
    }
    implicit def toJsPathHelper(path: JsPath): JsPathHelper = new JsPathHelper(path)
    
    implicit val someoneReads: Reads[Someone] = (
      (JsPath \ "firstName").trimmedString and
      (JsPath \ "lastName").trimmedString
    )(Someone.apply _)