1

I have a:

case class Product( 
    id: Option[Int],
    name: String,
    measure: Int,
    qty: Double = 0
)

and implicit json Reads in the Controller:

implicit val productReads: Reads[Product] = (
  (JsPath \ "id").readNullable[Int] and
  (JsPath \ "name").read[String] and
  (JsPath \ "measure").read[Int] and
  (JsPath \ "qty").read[Double].orElse(Reads.pure(0))
)(Product)

and here createProduct action:

def createProduct = DBAction(parse.json) { implicit rs =>
    rs.request.body.validate[Product].map { product =>
    Logger.info(s"createProduct product:$product")
    //...
    Ok(toJson(product))
  }.recoverTotal { errors =>
    BadRequest(errors.toString)
  }
}

So, the qty field has a default value 0. If client has not sent this field, the parser needs to get a default value, but when I want try create a product, the following error appears:

JsError(List((/qty,List(ValidationError(error.path.missing,WrappedArray()))))

Following JSON client sent:

{
    "measure": 1,
    "name": "meat"
}

Why?, Anybody know where my mistake is?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
SBotirov
  • 13,872
  • 7
  • 59
  • 81

2 Answers2

4

I tried running this in the REPL using play console, and everything is working just fine. orElse works just fine with Double. Pasting in the following:

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class Product( 
    id: Option[Int],
    name: String,
    measure: Int,
    qty: Double = 0
)

implicit val productReads: Reads[Product] = (
   (JsPath \ "id").readNullable[Int] and
   (JsPath \ "name").read[String] and
   (JsPath \ "measure").read[Int] and
  (JsPath \ "qty").read[Double].orElse(Reads.pure(0))
)(Product)

Json.parse("""{"measure": 1, "name": "meat"}""").validate[Product]

returns:

play.api.libs.json.JsResult[Product] = JsSuccess(Product(None,meat,1,0.0),)

It seems as though there's another Reads[Product] defined in the scope of def createProduct instead of the one you provided, otherwise it should be working. JSON macro perhaps?

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • ooh, you're absolutely right @LimbSoup, I checked the turn I remain old "implicit val productFormat = Json.format[Product]", thank you very much @LimbSoup!!! – SBotirov Jun 03 '14 at 04:57
0

AFAIK the Play JSON library does not support default case class values. See also this question.

Community
  • 1
  • 1
Manuel Bernhardt
  • 3,135
  • 2
  • 29
  • 36