#Basics of file upload, LiveView

1 messages · Page 1 of 1 (latest)

royal matrix
#

Hello!

I am trying to get file uploads to work in liveview and i think im getting pretty close, however, as this is my first time working with elixir i am getting stuck on a error message that i cant really interpret from the output.

This is my definition that i use in a HEEX file with no paramteters, can i not do this?:

  defp has_uploaded_entries() do 
    not Enum.empty?(uploaded_entries(@socket, @upload_ref))
  end

Socket should be assigned internally in the mount definition from what im understanding? Is my @upload_ref definition whats causing the issue?:

  @upload_ref :uploads

  def mount(_params, _session, socket) do
    File.mkdir_p!(@upload_dir)

    {:ok, 
      socket 
      |> assign(:uploads_in_progress, [])
      |> assign(:uploaded_files, [])
      |> allow_upload(@upload_ref, max_entries: 5, auto_upload: false, accept: :any)}
  end

This is the error i am getting:

no function clause matching in Phoenix.LiveView.Upload.uploaded_entries/2

Called with 2 arguments --
    1. nil
    2. :uploads

Why would socket be nil in this case? Isnt the socket connected and alive before the JS is fully loaded? I'll send the HEEX code below just so that i dont leave anything out:

      <div class="mt-8">
        <.progress_display entries={@uploads_in_progress} />

        <%= if has_uploaded_entries() do %>
          <button phx-click="complete_upload" class="mt-4 w-full bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-3 px-4 rounded-lg shadow transition duration-150">
            Finalize Uploads
          </button>
        <% end %>

        <.file_list files={@uploaded_files} />
      </div>

Any help is appreciated as i really like elixir so far, it just feels so smooth coming from c#, c and python before.

covert cedar
#

I believe you're getting confused (and it's totally understandable) between @upload_ref, which is a Module attribute, whereas @socket in a HEEx template, is a shortcut for Map.fetch!(assigns, :socket). I honestly can't find anywhere that even describes that syntax anymore, so your confusion is understandable.

To do what you are wanting to do, you would need to pass the socket to your has_upload_entries(@socket) function.

However, that's not really the correct solution anyways. The @uploads assign will get auto-populated with entries by LiveView already. I suggest renaming your @upload_ref to something other than uploads, but if you leave it, @uploads.uploads will contain the upload entries already. Phoenix.LiveView.upload_entries/2 is really meant for the elixir side to easily reach into the socket assigns and get entries, it's not meant for heex code.

I really suggest sticking closely to the Uploads guide to begin with... the upload feature is pretty complicated and tough to understand at first.

#

Also, you probably got the warning:

warning: undefined module attribute @socket, please remove access to @socket or explicitly set it before access

#

I suggest not ignoring any warnings... your code should run cleanly with no warnings and no errors.

royal matrix
#

Thanks for the help, i went with the basic example and got it working from there, at the moment im reading up more on how phx-hooks work as they are the key for my drag and drop solution i think. This clears it up tho, thanks a lot. I can upload files now, all i'm missing is the ability to do drag and drop of folders, im guessing i will need to manually traverse the diretory on upload and create folders that dont already exists server side.

Thanks for the quick reply!

#

How do i mark this as solved 🤔