I'm using play 2.2.0 Reads for validating incoming request in my application.
I'm trying to implement a very simple thing with json API. I have a json like this:
{
"field1": "some value",
"field2": "some another value"
}
I already have Reads
that checks for other stuff like minimal length
case class SomeObject(field1: String, field2: String)
implicit val someObjectReads = (
(__ \ "field1").read(minLength[String](3)) ~
(__ \ "field2").read(minLength[String](3))
)(SomeObject)
I want to create a parser combinator that will match values of two fields and return JsSuccess
if values are equal and otherwise JsError
and combine it with existing Reads
.
How can I achieve this?
UPDATE: clarified the question and changed the code.
You can use filter
to do further validation on parsed values:
import play.api.data.validation._
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
case class SomeObject(field1: String, field2: String)
implicit val someObjectReads = (
(__ \ "field1").read(minLength[String](3)) ~
(__ \ "field2").read(minLength[String](3))
)(SomeObject).filter(
ValidationError("field1 and field2 must be equal")
) { someObject =>
someObject.field1 == someObject.field2
}
If you want the error message to be listed against each field, then you'll have to use flatMap
, eg:
implicit val someObjectReads = (
(__ \ "field1").read(minLength[String](3)) ~
(__ \ "field2").read(minLength[String](3))
)(SomeObject).flatMap { someObject =>
Reads { _ =>
if (someObject.field1 == someObject.field2) {
JsSuccess(someObject)
} else {
JsError(Seq(
JsPath("field1") -> Seq(ValidationError("field1 and field2 must be equal")),
JsPath("field2") -> Seq(ValidationError("field1 and field2 must be equal"))
))
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With