Nate Busa
Nate Busa

Reputation: 1650

How to define default values optional fields in play framework forms?

I am implementing a web api using the scala 2.0.2 play framework. I would like to extract and validate a number of get parameters. And for this I am using a play "form" which allows me to define optional fields.

Problem: For those optional fields, I need to define a default value if the parameter is not passed. The code is intended to parse correctly these three use cases:

I have come up with the following code:

def test = Action {
  implicit request =>

  case class CData(top:Int)

  val p = Form(
    mapping(
      "top" -> optional(number)
    )((top) => CData($top.getOrElse(42))) ((cdata:CData) => Some(Some(cdata.top)))
  ).bindFromRequest()

  Ok("all done.")
}

The code works, but it's definitely not elegant. There is a lot of boiler plate going on just to set up a default value for a missing request parameter.

Can anyone suggest a cleaner and more coincise solution?

Upvotes: 6

Views: 6456

Answers (2)

rssh
rssh

Reputation: 464

in Play 2.1

val p = Form(
    mapping(
      "top" -> default(number,42)
    )(CData.apply)(CData.unapply)
  ).bindFromRequest()

will do what you want.

Upvotes: 12

lambdas
lambdas

Reputation: 4090

This is router job to validate query string parameters. Just define your parameter in the routes file:

GET /test controllers.Application.test(top: Int ?= 42)

And add top as a parameter to your controller method:

def test(top: Int) = Action {
  // Use top here
  val data = CData(top)
}

Then, Play do all the validating work for you. Note how default value specified using ?= syntax.

You should use forms only for POST requests.

Update:

If you wish to manually check parameters, then you could define helper method:

def getQueryParam(key: String, default: String)(implicit request: RequestHeader) =
  request.queryString.get(key).flatMap(_.headOption).getOrElse(default)

And use it inside your controller methods:

def test = Action { implicit request =>
  val top = getQueryParam("top", "42")
  ...

But by doing this you lose type checking. Of course you can define helpers for each type, i.e. getIntParam, getStringParam and so on, but Play already contains safe router implementation, designed to solve such kind of problems. I advice you to use routing mechanism instead of manual checking.

Upvotes: 9

Related Questions