LiveView File Uploads issue when the upload form is in a LiveComponent - Solved

So the setup is a PostLive that renders a bunch of posts, as well as a form, but the form is it’s own LiveComponent rendered like: <%= live_component @socket, MyAppWeb.PostFormComponent, id: :post_form %>. The actual handle_event for the post form, is handled in PostLive, not PostFormComponent

I have the socket = allow_upload(socket, :file, ...) code in both the PostLive mount function, and the PostFormComponent mount function. The form displays correctly, but something seems to happen when the form gets submitted where the ref ids get changed around. Here’s the error I get:

** (KeyError) key "phx-Fkoosv06ZyDQXSrD" not found in: %{"phx-Fkoosvzak-DQXSqj" => :file}
    :erlang.map_get("phx-Fkoosv06ZyDQXSrD", %{"phx-Fkoosvzak-DQXSqj" => :file})
    (phoenix_live_view 0.15.0) lib/phoenix_live_view/upload.ex:166: Phoenix.LiveView.Upload.get_upload_by_ref!/2
    (phoenix_live_view 0.15.0) lib/phoenix_live_view/channel.ex:949: anonymous fn/3 in Phoenix.LiveView.Channel.maybe_update_uploads/2
    (stdlib 3.13) maps.erl:233: :maps.fold_1/3
    (phoenix_live_view 0.15.0) lib/phoenix_live_view/channel.ex:200: Phoenix.LiveView.Channel.handle_info/2

Is there something else I need to do when rendering a form from a component that submits to a live_view?

Nevermind. I ended up figuring it up. I removed my allow_upload/3 call from the component, and added an update/2 call like this:

def update(%{uploads: uploads}, socket) do
    socket = assign(socket, :uploads, uploads)
    {:ok, socket}
  end

That got it working! Loving the new LiveView uploader!

1 Like

Hello :slight_smile:

I’m facing a similar issue. The file upload works when I create a new record. But if I want to edit the same record and replace the image, I got an error.

[error] GenServer #PID<0.590.0> terminating
** (stop) exited in: GenServer.call(#PID<0.582.0>, {:phoenix, :register_entry_upload, %{channel_pid: #PID<0.590.0>, cid: 2, entry_ref: "0", ref: "phx-FmMj3fS0VMjc6gMD"}}, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir 1.11.3) lib/gen_server.ex:1027: GenServer.call/3
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/upload_channel.ex:36: Phoenix.LiveView.UploadChannel.join/3
    (phoenix 1.5.7) lib/phoenix/channel/server.ex:376: Phoenix.Channel.Server.channel_join/4
    (phoenix 1.5.7) lib/phoenix/channel/server.ex:298: Phoenix.Channel.Server.handle_info/2
    (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4
    (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6
    (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: {Phoenix.Channel, %{"token" => "SFMyNTY.g2gDaAJhBHQAAAADZAADY2lkYQJkAANwaWRYZAANbm9ub2RlQG5vaG9zdAAAAkYAAAAAAAAAAGQAA3JlZmgCbQAAABRwaHgtRm1NajNmUzBWTWpjNmdNRG0AAAABMG4GANpqk5h3AWIAAVGA.bnP5nHScf2qL4sgC9eefLq4TJtPAnwlQ-9uxb71KHKM"}, {#PID<0.576.0>, #Reference<0.3856547095.2585264130.229322>}, %Phoenix.Socket{assigns: %{}, channel: Phoenix.LiveView.UploadChannel, channel_pid: nil, endpoint: SchlaflosWeb.Endpoint, handler: Phoenix.LiveView.Socket, id: "users_sessions:lvC_a0vlcg_rRKPNy8p509WfZB_7QOKGK35-ZN3MrE8=", join_ref: "14", joined: false, private: %{connect_info: %{session: %{"_csrf_token" => "E33t4FuzJCHG9Wlqqspgzsb8", "live_socket_id" => "users_sessions:lvC_a0vlcg_rRKPNy8p509WfZB_7QOKGK35-ZN3MrE8=", "user_token" => <<150, 240, 191, 107, 75, 229, 114, 15, 235, 68, 163, 205, 203, 202, 121, 211, 213, 159, 100, 31, 251, 64, 226, 134, 43, 126, 126, 100, 221, 204, 172, 79>>}}}, pubsub_server: Schlaflos.PubSub, ref: nil, serializer: Phoenix.Socket.V2.JSONSerializer, topic: "lvu:0", transport: :websocket, transport_pid: #PID<0.576.0>}}
State: #Reference<0.3856547095.2585264130.229324>
[error] exited in: GenServer.call(#PID<0.582.0>, {:phoenix, :register_entry_upload, %{channel_pid: #PID<0.590.0>, cid: 2, entry_ref: "0", ref: "phx-FmMj3fS0VMjc6gMD"}}, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
[error] GenServer #PID<0.589.0> terminating
** (KeyError) key "phx-FmMj3fS0VMjc6gMD" not found in: %{"phx-FmMj363mGfjDuQCH" => :live_image}
    :erlang.map_get("phx-FmMj3fS0VMjc6gMD", %{"phx-FmMj363mGfjDuQCH" => :live_image})
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/upload.ex:166: Phoenix.LiveView.Upload.get_upload_by_ref!/2
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/upload.ex:107: Phoenix.LiveView.Upload.update_progress/4
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/channel.ex:139: anonymous fn/4 in Phoenix.LiveView.Channel.handle_info/2
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/diff.ex:194: Phoenix.LiveView.Diff.write_component/5
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/channel.ex:1011: Phoenix.LiveView.Channel.write_socket/4
    (phoenix_live_view 0.15.4) lib/phoenix_live_view/channel.ex:137: Phoenix.LiveView.Channel.handle_info/2
    (stdlib 3.14) gen_server.erl:689: :gen_server.try_dispatch/4
    (stdlib 3.14) gen_server.erl:765: :gen_server.handle_msg/6
    (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{event: "progress", join_ref: "13", payload: %{"cid" => 2, "entry_ref" => "0", "event" => nil, "progress" => %{"error" => "failed"}, "ref" => "phx-FmMj3fS0VMjc6gMD"}, ref: "17", topic: "lv:phx-FmMj3d-caeD9LAFB"}

Was that the issue you had? How did you solved it exactly?

There was some gaps in the documentation with regards to using with phx-modal that comes with the CLI. For me was having mount on index enable allow_uploads, then chaining down to the form through the modal options. I made a demo repo to help others and undoubtedly myself in the future:

1 Like