Genie.jl icon indicating copy to clipboard operation
Genie.jl copied to clipboard

Simple, consistant, multi-value form behaviour

Open tecosaur opened this issue 3 years ago • 1 comments

The problem with the current behaviour

At the moment, form support is a bit messy. Repeating inputs with the same name causes the last value to overwrite all the others, unless the name ends with [] in which case a list of all provided values is formed — unless you're using a multipart form, in which case multiple values with [] doesn't work at all.

I assume the [] at the end convention is taken from PHP which does this, but I find it needlessly complicates the situation. Consider the following examples:

  • foo=1&foo=2
  • foo[]=1&foo[]=2
  • foo[]=1&foo=2
  • foo=1&foo[]=2
  • foo=1&foo[]=2&foo=3

The first two have a semi-obvious behaviour, but beyond that, the situation … deteriorates.

It's also a bit annoying to write Symbol("name[]") instead of :name when accepting multiple values.

I think we can do better.

My proposal

I propose a breaking change for v5, to make form values be handled in a simpler, and more consistent manner.

Treat all form fields as multi-value, with no ifs, buts or ands

Consider the following example:

<form>
  <input type="text" name="foo" value="1"/>
  <input type="text" name="foo" value="2"/>
  <input type="text" name="bar" value="3"/>
</form>

Depending on whether you put [] after foo or not you'll either see

Dict{Symbol, String} with 2 entries:
  :bar => "3"
  :foo => "2"

or

Dict{Symbol, Union{String, Vector{String} with 2 entries:
  :bar => "3"
  Symbol("foo[]") => ["1", "2"]

By treating all form fields as multi-value, you'd have the following result

Dict{Symbol, Vector{String}} with 2 entries:
  :bar => ["3"]
  :foo => ["1", "2"]

This has a few advantages:

  • No information is lost by default
  • No more hassle with [] in the name or Symbol("...[]")
  • It's simpler to reason about mentally, by having a simpler model and more uniform data type
  • It's easy to obtain single-value behaviour with payload[:name][end]

tecosaur avatar Feb 07 '22 11:02 tecosaur

Thank you.

I agree with some of the downsides of the current approach, like the Symbol(...) pattern which is too verbose. On the other hand, I'm not a big fan of having all the params as Vectors, especially as in the majority of the cases it will be just one value.

Leaving it open for discussions to get more input before picking the v5 features.

essenciary avatar Feb 15 '22 17:02 essenciary