Greetings,
Previous title of this post: Phoenix.new generated params not extracted on submit of 2nd step in multi step form on liveview
I am revising this post completely because I used phx.gen.live
to generate a simple test case and it confirmed the previous behavior but now I have two apparent fixes.
My question: Are either of the following two fixes appropriate or is something else wrong?
The problem is that this fails on second submit because params
is an empty map:
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<.header>
{@page_title}
<:subtitle>Use this form to manage junk records in your database.</:subtitle>
</.header>
<%= if @step == :details do %>
<.form for={@form} id="junk-form" phx-change="validate" phx-submit="save">
<.input field={@form[:name]} type="text" label="Name" />
<.input field={@form[:address]} type="text" label="Address" />
<footer>
<.button phx-disable-with="Saving..." variant="primary">Save Junk</.button>
<.button navigate={return_path(@current_scope, @return_to, @junk)}>Cancel</.button>
</footer>
</.form>
<% else %>
<.form for={@form} id="junk-form" phx-change="validate" phx-submit="save">
<footer>
<.button phx-disable-with="Saving..." variant="primary">Save Junk</.button>
<.button navigate={return_path(@current_scope, @return_to, @junk)}>Cancel</.button>
</footer>
</.form>
<% end %>
</Layouts.app>
"""
end
There are two ways I can make it pass.
One way is to patch the event handler:
# def handle_event("save", %{"junk" => junk_params} = params, socket) do
def handle_event("save", params, socket) do
# A PATCH:
junk_params =
if Map.has_key?(params, "junk") do
params["junk"]
else
socket.assigns.form.params
end
junk = %Junk{user_id: socket.assigns.current_scope.user.id}
changeset =
Junkcontxt.change_junk(socket.assigns.current_scope, junk, junk_params)
|> Map.put(:action, :validate)
case socket.assigns.step do
:details ->
{:noreply,
socket
|> assign(:step, :payment)
|> assign(:form, to_form(changeset))
|> put_flash(:info, "Organization details look good! Now let's set up payment.")}
:payment ->
save_junk(socket, socket.assigns.live_action, junk_params)
end
end
Or, another way is to include hidden inputs in the form:
<% else %>
<.form for={@form} id="junk-form" phx-change="validate" phx-submit="save">
<.input field={@form[:name]} type="hidden" />
<.input field={@form[:address]} type="hidden" />
<footer>
<.button phx-disable-with="Saving..." variant="primary">Save Junk</.button>
<.button navigate={return_path(@current_scope, @return_to, @junk)}>Cancel</.button>
</footer>
</.form>
<% end %>
Thanks in advance.