Search code examples
jsonscalaplayframeworkbigdecimal

How to return 2 decimal points for BigDecimal in JSON response from Scala/Play Framework


Here is my case class.

case class DecimalWrapper(money: BigDecimal, type: String)

object DecimalWrapper {
    implicit val decimalWrapperMarshaller = Json.format[DecimalWrapper]
}

When trying to do Json.toJson(DecimalWrapper(2, "whole sale")) it returns

{
   "money": 2
   "type": "whole sale"
}

what I would like it to return is 2.00 for the money field.

I couldn't find out a way to specify a custom serialiser to always return 2 decimal points with rounding HALF_UP.

Anyone please kindly help?

Regards Tin


Solution

  • Might seem more involved but it'd be a good idea to define a separate writes for BigDecimal if you intend to reuse that writes logic throughout your application. One thing to note is you have to use it explicitly, you can't declare it implicit as there is already an implicit writes defined for BigDecimal.

    val decimalWrites = new Writes[BigDecimal]{
      def writes(o: BigDecimal): JsValue = JsString(o.setScale(2, RoundingMode.HALF_UP).toString())
     }
    
    implicit val decimalWrapperWrites: Writes[DecimalWrapper] = (
      (JsPath \ "money").write[BigDecimal](decimalWrites) and
      (JsPath \ "type").write[String]
    )(unlift(DecimalWrapper.unapply))