Given the following JSON..
{ "ask":"428.00", "bid":"424.20" }
... I need to convert the values of ask
and bid
to numbers:
{ "ask": 428.00, "bid": 424.20 }
To do that, I've created a validator that reads the string value and passes it to method toNumber
, which validates and converts the given string:
def validate = ( ((__ \ 'ask).json.pickBranch(Reads.of[JsString] <~ toNumber)) ~ ((__ \ 'bid).json.pickBranch(Reads.of[JsString] <~ toNumber)) ).reduce private def toNumber(implicit reads: Reads[String]) = { Reads[Double](js => reads.reads(js).flatMap { value => parse[Double](value) match { case Some(number) => JsSuccess(number) case _ => JsError(ValidationError("error.number", value)) } } ) }
The code above only validates the value but of course does not replace the original string with the converted number. How do I convert string values to numbers while validating?
EDIT
Just wanted to share the solution provided by Ben:
def validate = ( ((__ \ 'ask).json.update(toNumber)) ~ ((__ \ 'bid).json.update(toNumber)) ).reduce private def toNumber(implicit reads: Reads[String]) = { Reads[JsNumber](js => reads.reads(js).flatMap { value => parse[Double](value) match { case Some(number) => JsSuccess(JsNumber(number)) case _ => JsError(ValidationError("error.number", value)) } } ) }