Simple form error when try to use the %Plug.Con in the 'for'

Hi all, I’m really new in the Elixir/Phoenix world, so first of all sorry if I ask something in the wrong place.

The thing is that if in an new Phoenix project (I’m following the example from the Phoenix Programming 1.4 but with the latest Phoenix version) I try to create a simple_form with the %Plug.Conn{} struct in the for property:

<.simple_form
  :let={f}
  for={@conn}
  as={:session}
  phx-change="validate"
  action={~p"/sessions"}>
  <.input field={f[:username]} label="Username" />
  <.input field={f[:password]} type="password" label="Password" />

  <:actions>
    <.button>Log In</.button>
  </:actions>
</.simple_form>

The app crashes with the following error

Protocol.UndefinedError at GET /sessions/new
protocol Phoenix.HTML.FormData not implemented for %Plug.Conn{adapter: {Bandit.Adapter, :...}, assigns: %{connection: %{}, layout: {RumblWeb.Layouts, "app"}, ...

Expected behavior

As soon as I used en empty struct or a nil, the app works perfectly.

<.simple_form
  :let={f}
  for={#{}}
  as={:session}
  phx-change="validate"
  action={~p"/sessions"}>
  <.input field={f[:username]} label="Username" />
  <.input field={f[:password]} type="password" label="Password" />

  <:actions>
    <.button>Log In</.button>
  </:actions>
</.simple_form>

I also replicate the error in a new Phoenix ap, without anything else rather than the simple_form and the error happens in the same way.

Any idea about what is going on? Thanks!

Hello and welcome!

You can make a form for a %Plug.Conn{}, it needs to be either a bare map or like the error suggests, a %Phoenix.HTML.FormData{}. LiveView comes with a helper to transform a changeset into this:

def mount(_params, _session, socket) do
  changeset = MyApp.Accounts.some_user_changeset()

  socket = assign(socket, :form, to_form(changeset))

  {:ok, socket}
end

Then:

<.simple_form for={@form} ... >...</.simple_form>

Another word of advice, do not use let={f} on parent forms like that—it breaks change tracking. Though it doesn’t go into detail, see here.

1 Like

Thanks @sodapopcan!

My question is why is in the Programming Phoenix 1.4 book the “for=@conn” if it can only be a Map or a FormData? Am I the only one with this error :joy:?

Maybe something change in some of the latest Phoenix versions?

Ohhhhhh! Weird. Though Phoenix 1.4 is quite old, so maybe that used to be a thing? I only started using it at 1.5 myself so I can’t confirm. In that version we’d pass a changeset directly to for.

1 Like

Yes :pensive:, quite old.

I’m struggling a lot to follow the book searching for the new features (like not longer use Views and use HTML instead).

Thanks again!

1 Like

I recommend working through the Official Guides. They are really good! A tad different than the guides from other ecosystems, at least I like to think so. I’m certainly bias but Elixir does have a reputation for generally stellar documentation (it’s not without its warts) and it’s usually the first place you want to go. Always take note of the GUIDES vs MODULES tabs in hexdocs.pm. MODULES is for reference but GUIDES is usually great for learning from scratch for many packages.

2 Likes

Found the solution!

1 Like