Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
345 views
in Technique[技术] by (71.8m points)

scala - How to access my forms properties when validation fails in the fold call?

I have an action where my form posts too like:

def update() = Action { implicit request =>
  userForm.bindFromRequest().fold(
     errorForm => {
        if(errorForm.get.isDefined) {
           val id = errorForm.get.id // runtime error during form post
        }
        BadRequest(views.html.users.update(errorForm))
     },
     form => {
         val id = form.id   // works fine!
         Ok("this works fine" + form.name)
     }
  )

}

When I do the above, I get an error:

[NoSuchElementException: None.get]

If there are no validation errors, the form post works just fine in the 'success' part of the fold call.

I need to get the id value in the error section, how can I do that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When a Form fails to bind to a model, all you will have available is the data in the form of a Map[String, String] and the validation errors (essentially). So you can access the values as Strings, but keep in mind they also might not be available.

For example:

case class Test(id: Int, name: String)

val testForm = Form {
    mapping(
        "id" -> number,
        "name" -> nonEmptyText
    )(Test.apply)(Test.unapply)
}

Now try to bind to this Form with a missing name field:

scala> val errorForm = testForm.bind(Map("id" -> "1"))
errorForm: play.api.data.Form[Test] = Form(ObjectMapping2(<function2>,<function1>,(id,FieldMapping(,List())),(name,FieldMapping(,List(Constraint(Some(constraint.required),WrappedArray())))),,List()),Map(id -> 1),List(FormError(name,List(error.required),List())),None)

You can access individual fields using apply. And each Field has a value method with returns Option[String].

scala> errorForm("name").value
res4: Option[String] = None

scala> errorForm("id").value
res5: Option[String] = Some(1)

Possible usage:

errorForm("name").value map { name =>
    println("There was an error, but name = " + name)
} getOrElse {
    println("name field is missing")
}

Keep in mind that the non-bound data is only a String, so more complicated data structures may be harder to access, and most of the time it will not be type safe.

Another way is to access the raw Map directly:

scala> errorForm.data
res6: Map[String,String] = Map(id -> 1)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...