Hello everyone,
I’ve been writing an admin area in Phoenix LiveView to learn it and admin things. If I’m honest it’s been both amazing and quite frustrating, probably because my mental model is wrong.
I am thinking that my changeset or form is all of the data and information I need to be able to display my form.
Inside it I have a list of events and have managed despite many other examples that seem to duplicate the data for their own purposes I simply have a changeset and I’m making changes to it such as appending %Events{} to the association with put_assoc and get_assoc. It was really painful finding the incantations for doing this but I eventually got to this:
def handle_event("add_class_event", params, socket) do
changeset =
socket.assigns.changeset
|> Ecto.Changeset.put_assoc(
:events,
Ecto.Changeset.get_assoc(socket.assigns.changeset, :events) ++
[
%ClassEvent{}
]
)
{:noreply, assign(socket, :changeset, changeset)}
end
Okay great, so the next thing I started thinking was, okay each event has some very custom attributes/subforms that I will need to reveal when the “type” select is changed. Fine we can add phx-changed=“type-dropdown” then handle this event in out live view! We should simply just be able to update our changeset and the form should reflect this and change based on that data. It does not.
def handle_event(
"type-dropdown",
%{"class" => %{"events" => changed}} = params,
socket
) do
index = changed |> Map.keys() |> Enum.at(0) |> String.to_integer()
value = changed |> Map.values() |> Enum.at(0) |> Map.get("type")
class_events = Ecto.Changeset.get_assoc(socket.assigns.changeset, :events)
updated_class_event =
class_events |> Enum.at(index) |> Ecto.Changeset.put_change(:type, value) |> IO.inspect()
new_class_events = List.replace_at(class_events, index, updated_class_event)
changeset =
socket.assigns.changeset
|> Ecto.Changeset.put_assoc(
:events,
new_class_events
)
{:noreply, socket |> assign(assigns: %{changeset: changeset})}
end
Firstly this seems like a bit of a mess to be able to change one value in the form and secondarily it does not work. Is there something about changesets, forms and live view that I am misunderstanding? Maybe you are all going to tell me just add a list for the event-type dropdown values and have that be the source of truth, it just seems to go against how I would model this in react and changesets seem like such a clean pattern it seems odd if I can’t keep all my data in one place while editing my form.