Max
Max

Reputation: 2552

Cannot bind a given Map in a Form using Play for Scala

I cannot bind a value into a Form[M]. It seems it doesn't work because of the List: if I turn List[String] into String, it works. Here's the code

case class SearchCriteria (
  val q: Option[String],
  var fq_chset: List[String]
)

val theSearchForm: Form[SearchCriteria] = Form(
  mapping(
    "q" -> optional(text),
    "fq_chset" -> list(text)
  )
)(SearchCriteria.apply _)(SearchCriteria.unapply _)

def foldSearchCriteria(searchForm: Form[SearchCriteria]): Either[Throwable, SearchCriteria] = {
  foldForm[SearchCriteria](searchForm, { searchCriteria =>
    Logger.debug(searchCriteria.toString())
    Right(searchCriteria)
  })
}

def foldForm[F](aForm: Form[F], onSuccess: F => Either[Throwable,F]): Either[Throwable,F] = {
  aForm.fold(
    hasErrors = { form => 
      Left(new RuntimeException("Errors while folding Form"))
    },
    success = { formData => 
     onSuccess(formData)
   } 
  )   
}

What I get is:

foldSearchCriteria(theSearchForm.bind(Map("q" -> "ValueQ")))
>> SearchForm( Some(ValueQ), None ) )


foldSearchCriteria(theSearchForm.bind(Map("fq_chset" -> "Value1")))
>> SearchForm( None, Some(List()) )

Any idea?

Upvotes: 0

Views: 204

Answers (1)

Mikesname
Mikesname

Reputation: 8901

In order to bind list values, the key has to have list indices appended (e.g. [0], [1]). Try this:

theSearchForm.bind(Map("fq_chset[0]" -> "Value1"))

Note: if you're binding from request data it's sufficient to just use [] as a suffix, but this doesn't work when binding from a map with string values because you need to disambiguate the keys.

You can also use bindFromRequest with a Map[String,Seq[String]] argument and you don't have to specify the exact indices:

theSearchForm.bindFromRequest(Map("fq_chset[]" -> Seq("Value1")))

Upvotes: 2

Related Questions