Reputation: 128
I'm using play's json libraries to parse json sent to me by javascript. Everything worked fine during initial testing but I have discovered that the various front ends send json values bare or wrapped in quotes. This can change from time to time so my parsing fails as what looks like a float one data looks like a string the next.
I'm using implicit Reads to parse to a model and really want to continue to do that. Currently I have:
case class dsource (
A: String,
B: Int,
C: Float,
D: Float,
E: Float,
F: Float,
G: Float
)
object dsource {
implicit val dsourceaReads: Reads[dsource] = (
(JsPath \ "A").read[String] and
(JsPath \ "B").read[String].map(_.toInt) and
(JsPath \ "C").read[String].map(_.toFloat) and
(JsPath \ "D").read[String].map(_.toFloat) and
(JsPath \ "E").read[Float] and
(JsPath \ "F").read[Float] and
(JsPath \ "G").read[Float]
) (dsource.apply _)
}}
I want to avoid preprocessing the Json and I can't control what the front end sends me, I need to handle the value wether it is encased in quotes or not. I guess this is the challenge with having a weakly typed front end sending to a strongly typed back end.
Any suggestions?
Thanks in advance.
Upvotes: 1
Views: 55
Reputation: 170723
You could create helpers:
val maybeQuotedInt: Reads[Int] = Reads {
js => js.validate[String].map(_.toInt).orElse(js.validate[Int])
}
// similar for Float/Double/etc
and then use them as
(JsPath \ "A").read[String] and
(JsPath \ "B").read(maybeQuotedInt) and
(JsPath \ "C").read(maybeQuotedFloat) and ...
This is untested, just going from the documentation, so might need some changes but this approach should work.
Upvotes: 1