nherzing

nherzing

Handling live upload timeouts

I’m wondering if there is a way to be notified of the scenario where an in-progress LiveView Upload times-out and is canceled. In my experience, the upload entry is silently removed from socket.assigns.uploads.upload_name.entries without alerting the owning liveview in any way. This makes it difficult to tell what actually happened and to act accordingly. Is there some api that I am missing or some other way of handling this that I haven’t thought of?

Detailed Reproduction and Explanation

Suppose we have the following liveview with a form with a single live upload.

defmodule MyAppWeb.SimpleLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok,
     socket
     |> allow_upload(:my_upload,
       accept: ~w(image/jpeg image/png),
       auto_upload: true,
       progress: &handle_progress/3,
       # very low to reproduce timeouts
       chunk_timeout: 1
     )
     |> assign(progress: 0, submitted: false)}
  end

  defp handle_progress(:my_upload, entry, socket) do
    IO.inspect(entry.progress, label: "Progress")
    {:noreply, assign(socket, progress: entry.progress)}
  end

  def handle_event("validate", _params, socket) do
    IO.inspect("VALIDATE")
    {:noreply, socket}
  end

  def handle_event("save", _params, socket) do
    IO.puts("SUBMIT")
    IO.inspect(socket.assigns.uploads, label: "Uploads")
    {:noreply, assign(socket, submitted: true)}
  end

  def render(assigns) do
    ~H"""
    <form class="group" id="upload-form" phx-submit="save" phx-change="validate">
      <label class="block">
        <.live_file_input upload={@uploads.my_upload} class="hidden" /> Upload
      </label>
      <div><%= @progress %> / 100</div>

      <button type="submit">Submit</button>

      <div class="hidden group-[.phx-submit-loading]:block ">
        Submitting
      </div>
      <%= inspect(@uploads[:my_upload]) %>
    </form>

    <div>Submitted: <%= @submitted %></div>
    """
  end
end

If you attempt to upload a file with this liveview, you’ll notice that the progress is updated on the first chunk upload. After that, the upload is canceled because we hit the very low chunk_timeout. (It’s set so low to force the reproduction. You can also reproduce by leaving it at the default of 10s and change your network speed via Chrome dev tools.) At this point, the entry is removed but our liveview was not notified of this and thus cannot update its state to reflect it. Thus, our progress state remains in a broken state.

Is there any way for our liveview to respond to the fact that the upload was canceled and that the entry has been removed? Of course we could conditionally render content based on the contents of socket.assigns.uploads.my_upload.entries but that feels wrong and doesn’t solve the problem of our assigns being in a weird state.

First Post!

sodapopcan

sodapopcan

This doesn’t feel wrong to me. You can fix the assigns by that checking my_upload.entries in the :my_upload callback and cleaning them up if it’s empty. Maybe someone else has a fancier solution but that’s how I would do it without a second thought :sweat_smile:

You can of course additionally also set some error state when this happens.

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement