Closed eriknaslund closed 1 month ago
to_form with a map uses https://github.com/phoenixframework/phoenix_html/blob/2b222dbf104b3ac952053de441b61f56f89f4bf8/lib/phoenix_html/form_data.ex#L80 under the hood, so probably the place to add the check would be in phoenix_html. I'm not sure if this is intentional or not, but @josevalim probably knows.
I think a PR that does :maps.next(:maps.iterator(map))
and check if the string is an atom and then warns would be welcome!
Well, I should have looked a couple lines below.. https://github.com/phoenixframework/phoenix_html/commit/2d2e2e9fcab76c376b07a9bbb7b2659bee591b46
We already have the warning 😃
@eriknaslund which version of phoenix_html are you using? I think the existing warning should be just fine, wdyt?
Should we hard fail then? Since we have been emitting the warning for a while?
Should we hard fail then? Since we have been emitting the warning for a while?
I'm not sure, I think a warning is probably good enough. It would be a breaking change to raise.
There is a bit of luck involved with the check currently, right? We only warn if the first key we get is an atom, but by chance the first one could be a string as well and only a later one an atom.
Is this something the type system could warn about in the future?
There is a bit of luck involved with the check currently, right? We only warn if the first key we get is an atom, but by chance the first one could be a string as well and only a later one an atom.
For small maps, atoms always come before strings, so it should be fine unless you have 32+ keys (or 16+?)
Is this something the type system could warn about in the future?
YES!
Alright then. I‘d say the existing warning is good enough for now :)
@SteffenDE I have to hang my head in shame and admit I was sloppy enough to simply miss the warning. It was indeed there (I was on phoenix_html 4.1.1).
I develop a bit of "warning-ignoritis" from time to time, seeing things like dependencies using Logger.warn
emitting warnings. This somehow tricks my brain that warnings are just "things that are kinda bad, but it still works" (like C compile warnings). That's completely on me, and I'll take Elixir's warnings more seriously from now on - sorry Elixir! :)
I completely get the rationale about avoiding breaking changes. Closing the issue seems sensible to me, since there is a warning in place.
@josevalim Now I'm looking forward to the type system even more :).
Environment
Actual behavior
Calling
to_form/2
on a map with atom keys seems to work, but it doesn't really. Here's a minimal snippet to demonstrate:The value set for the string key is displayed correctly, but the value for the atom key isn't.
I'm aware that this "bug" has already been raised as https://github.com/phoenixframework/phoenix_live_view/issues/2469. However I think we can do better, and have something that is even more helpful for the developer :)
Expected behavior
If you inspect the Form and the FormField structs you'll see the following:
The only (unexpected?) difference between the string and atom key is that
value
is set tonil
for the atom key...and therefore isn't displayed when rendering.I know the docs for
to_form/2
state that (_When you pass a map to toform/1, it assumes said map contains the form parameters, which are expected to have string keys.). However I think it'd be more user friendly to hard-fail if the developer tries to pass a map with atom keys.If you pass
to_form/2
a map with atom keys it returns something that almost works. These pseudo-failures are often hard to debug, because it looks like you're doing things right at first glance. Imo it'd be better to be strict about the inputs here.What do you think?