Live_upload is not working

I have a phoenix project with live_view
I generate a CRUD for one of my models
In the form_component I have

socket = allow_upload(socket, :doc, accept: ~w(.pdf), progress: &handle_progress/3, auto_upload: true)
{:ok, socket}

in my form_component_html I have

<.form
  let={f}
  for={@changeset}
  id="document-form"
  multipart={true}
  phx-target={@myself}
  phx-submit="save">

.
.
.

<%= live_file_input @uploads.doc, class: "form-control" %>

The thing is that there is no call to

defp handle_progress(:doc, entry, socket) do
    IO.inspect(entry, label: "=========================")
   
    {:noreply, socket}

What am I doing wrong?

my mix.exs file (part of it

defp deps do
    [
      {:bcrypt_elixir, "~> 2.0"},
      {:phoenix, "~> 1.6.5"},
      {:phoenix_ecto, "~> 4.4"},
      {:ecto_sql, "~> 3.6"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 3.0"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:phoenix_live_view, "~> 0.17.5"},
...

Any suggestions??

1 Like

You need to bind the phx-change on the form as well.

Validation occurs automatically based on any conditions that were specified in allow_upload/3 however, as mentioned previously you are required to bind phx-change on the form in order for the validation to be performed. Therefore you must implement at least a minimal callback:

@impl Phoenix.LiveView
def handle_event("validate", _params, socket) do
  {:noreply, socket}
end

From docs

Already did that, but still have a problem.
Thanks

Can you post your <.form tag call?

<.form
  let={f}
  for={@changeset}
  id="document-form"
  multipart={true}
  phx-target={@myself}
  phx-change="validate"
  phx-submit="save">

I am getting this warning

Compiling 1 file (.ex)
warning: got "@impl Phoenix.LiveView" for function handle_event/3 but this behaviour was not declared with @behaviour
  lib/invoice_web/live/document_live/form_component.ex:37: InvoiceWeb.DocumentLive.FormComponent (module)

The module is

defmodule InvoiceWeb.DocumentLive.FormComponent do
  use InvoiceWeb, :live_component

  alias Invoice.{Mosad, Workers}

Replace @impl Phoenix.LiveView with @impl Phoenix.LiveComponent to make the warning go away.

I really can’t tell why it’s not working. Is live_file_input inside the form tags? Does the handle_event callback for the validate event get called?

Called with error

[error] GenServer #PID<0.2365.0> terminating
** (KeyError) key "phx-FsbSShOELYd97Qil" not found in: %{"phx-FsbSSn_D-OuNTQWD" => :docinv}
    :erlang.map_get("phx-FsbSShOELYd97Qil", %{"phx-FsbSSn_D-OuNTQWD" => :docinv})
    (phoenix_live_view 0.17.5) lib/phoenix_live_view/upload.ex:186: Phoenix.LiveView.Upload.get_upload_by_ref!/2
    (phoenix_live_view 0.17.5) lib/phoenix_live_view/channel.ex:1056: anonymous fn/3 in Phoenix.LiveView.Channel.maybe_update_uploads/2
    (stdlib 3.16.1) maps.erl:410: :maps.fold_1/3
.
.
.
.

I found the solution.

You can’t just put this line

<%= live_file_input @uploads.doc %>

Because it is a component you have to set the phx-target

 <label class="btn btn-sm btn-info mt-2"
             phx-target={@myself}><%= gettext("Upload") %>
        <%= live_file_input @uploads.doc, class: "hidden" %>
  </label>
1 Like