Philip Munksgaard
unread,Jul 1, 2024, 2:27:30 AM (5 days ago) Jul 1Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to elixir-l...@googlegroups.com
Hi,
I'm a frequent user of the Access module, and I'm excited about the recent addition of Access.find/1 to support some use-cases I've had to work my way around in the past. However, now that I have it, the first thing I wanted to do actually applied to a map.
For context, I'm working with Ecto changesets in a Phoenix LiveView application. I'm working with a `Foo` schema that has an assoc containing a number of uploaded files. Whenever I edit a Foo, I want to be able to upload a new file, but only one at a time. I also want to be able to edit the attached descriptions to each of the files that are already uploaded. I have written some logic that only shows one live_file_input at a time, and I have written the following `save` function (following the pattern in the standard phx.gen.live templates):
```elixir
defp save(socket, :edit, foo_params) do
uploaded_entries_params = consume_uploaded_entries(socket, :file, &upload_consumer/2)
foo_params =
case uploaded_entries_params do
[] ->
foo_params
[upload_params] ->
update_in(
foo_params,
["foo_files", Access.find(&is_nil(&1["file_id"])), "file"],
&Map.merge(&1, upload_params)
)
end
case Foos.update_foo(socket.assigns.foo, foo_params) do
{:ok, foo} ->
{:noreply, push_patch(socket, to: socket.assigns.patch)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign_form(socket, changeset)}
end
end
```
The interesting bit is the `update_in` call, which takes the params generated by my `upload_consumer` and merges it with the params coming from the form submission. Unfortunately, this doesn't work, since `foo_params["foo_files"]` is a map of the form: `%{"0" => %{ ... }, ...}`
I was a bit surprised to find that Access.find/1 doesn't work with maps, but then I remembered that the same is true for Access.filter/1. My (very) cursory look at the implementation suggests that both of those are using Enum-functions, which _do_ in fact support maps, so I am wondering why that is not the case for the Access-functions? Would there be any interest in adding support for maps in Access.find/1 and Access.filter/1?
Best regards
Philip