The general problem is, when used with the update operations, both find/1
and filter/1 would have to build the original shape back, instead of simply
returning a list (which is what the Enum functions do). It could be done
for maps and filter, but I am not quite sure about find. Also, we need to
be careful to not promote traversals in maps (by using find) instead of
doing a per key operation.

On Mon, Jul 1, 2024 at 8:27 AM Philip Munksgaard <pmunksga...@gmail.com>
wrote:

> 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
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/d29a0d69-db72-4d2d-814e-5809c4f8da6f%40app.fastmail.com
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LuS16x9hhTLneJjEuJO5aWUXhjY4QU_sxyLVad%3Ddus7Q%40mail.gmail.com.

Reply via email to