question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for binding empty-string / invalid values for Option[PlayEnum] query string params to None instead of failing

See original GitHub issue

Unfortunately browsers submit input parameters even if their values are empty. This means that input myenum value=“” will send “?myenum=&…” which causes enumeratum to fail with “Cannot parse parameter myenum as an Enum”. In my specific case, myenum is a pulldown with optional filter values not required to be selected (“”, All), (“MyEnum.One”, One), etc. In my routes file I have “myenum: Option[MyEnum] ?= None” and expect that myenum=&… (the case where someone submits a form with a filter pulldown left at default value of “”) would return None.

I believe the best thing would be for enumeratum to treat empty parameters as None for enums defined as Option in routes file.

One solution could be making UrlBinders.scala only consider the first nonEmpty parameter:

 def queryBinder[A <: EnumEntry](
    ...
  def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, A]] = {
        // params.get(key).flatMap(_.headOption).map { p =>
        params.get(key).flatMap(_.find(_.nonEmpty)).map { p =>
          val maybeBound = ...

It could be better to add a new QueryStringBindable that treats Option[PlayEnum] in routes different than PlayEnum but I am not sure if that is possible or actually any better than above solution.

(BTW: thanks so much for enumeratum…I am blown away at how much better enum heavy code is with it and very sad how long I went (years!) without knowing there was a better way to do enum in scala. )

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
Enalmadacommented, Jul 28, 2018

The skepticism is completely justified and your title update is spot on. Your workarounds will give anyone that comes along with the same issue food for thought. I think the ticket can be closed for now as discussed/reopen if you ever feel like supporting it. While I chew on the view layer suggestion, I will start with my own binder like this (unless you would suggest something else):

trait MyEnum[A <: EnumEntry] extends PlayEnum[A] { self: Enum[A] =>
  override implicit val queryBindable: QueryStringBindable[A] = MyCustomBinders.queryBinder(self)
  override implicit val pathBindable: PathBindable[A] = MyCustomBinders.pathBinder(self)
}

By the way, I think enumeratum needs to be here so new users can find it easier: https://www.playframework.com/documentation/2.6.x/ModuleDirectory. Please consider submitting it unless you disagree.

0reactions
lloydmetacommented, Jul 28, 2018

Now I am trying to make sure each web developer wanting first class routing doesn’t have to reinvent the wheel of binders.

The point of Play and subsequently, this lib, is to make sure that doesn’t happen. There might be some differences in opinion given that not everyone uses Play for the same use-cases 😃

Seeing as how I, and quite a few others have been using enumeratum-play, and, the default Play binders with forms, query strings, etc for a few years now without needing the fail-invalid-values-to-None behaviour that you’re suggesting, I remain somewhat skeptical that this is the right path to go (or encourage), given that we’ve already identified workarounds for this specific use-case (adding an enum member for your view layer and doing translations across layers, writing your own binder)

I’ll leave this ticket open for a while longer to see if there is something there that will make me keener to maintain some more code, but in the mean time I’ve also amended the title of this ticket to be more specific.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handling query string parameters with no value in ASP.NET ...
Query strings are typically made of a sequence of key-value pairs, ... it will be interpreted as empty, and the model binding will...
Read more >
Inconsistent handling of invalid and empty strings for ...
I focused in one that expects BigDecimals as input query parameters. When empty string is sent, it is expected to receive the request...
Read more >
c# - Treat empty query string parameters as ...
I'm trying to understand what is you expected result. Is it that you want, in your example, that is the parameter is not...
Read more >
Invalid value for query param 'pcEnvironment' provided. Must ...
it's giving me an error -Error: Invalid value for query param 'pcEnvironment' provided. Must be a non-null, non-empty string. Thank You.
Read more >
How to set default query string parameter value for webapi?
Refer to the following steps: Create a custom model binder. //required reference: using Microsoft.AspNetCore.Mvc.ModelBinding; ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found