Rebecca Le

@sevenseacat

Got errors with file uploads in Phoenix LiveView 0.18?

Sep 29, 2022

Phoenix LiveView 0.18 is out, and it comes with a bunch of cool new features that I'm eager to take advantage of. However, it comes with a few hidden gotchas for upgraders from previous versions...

A couple of them I noticed were around file uploads, and previews of said file uploads.

My form doesn't do anything when I submit it, anymore...

tl;dr - upgrade to LiveView 0.18.1.

If you're seeing nothing happening after submitting a form with a file uploaded in it, but you are seeing JS errors in your console, you've probably run into this bug. It's already been fixed and released in LiveView 0.18.1, so upgrade to that and you're golden!

But now LiveView crashes when trying to preview an uploaded file ๐Ÿ˜ญ

You might be seeing something like the following:

[error] GenServer #PID<0.6974.0> terminating
** (ArgumentError) assign/3 expects a socket from Phoenix.LiveView/Phoenix.LiveComponent  or an assigns map from Phoenix.Component as first argument, got: %{class: "h-12", entry: %Phoenix.LiveView.UploadEntry{progress: 0, preflighted?: false, upload_config: :file, upload_ref: "phx-Fxk1x2smwKP_ntGC", ref: "0", uuid: "1b401f1c-d1ec-40b8-8213-502917d39ea4", valid?: true, done?: false, cancelled?: false, client_name: "truck.svg", client_relative_path: "", client_size: 1335500, client_type: "image/svg+xml", client_last_modified: 1661930597292}} You passed an assigns map that does not have the relevant change tracking information. This typically means you are calling a function component by hand instead of using the HEEx template syntax. If you are using HEEx, make sure you are calling a component using:

    <.component attribute={value} />

If you are outside of HEEx and you want to test a component, use Phoenix.LiveViewTest.render_component/2:

    Phoenix.LiveViewTest.render_component(&component/1, attribute: "value")


    (phoenix_live_view 0.18.1) lib/phoenix_component.ex:1176: Phoenix.Component.raise_bad_socket_or_assign!/2
    (elixir 1.14.0) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
    (phoenix_live_view 0.18.1) lib/phoenix_component.ex:2340: Phoenix.Component.live_img_preview/1
    (my_app 0.1.0) lib/my_app_web/live/components/forms/inputs/file_upload.ex:42: anonymous fn/3 in MyAppWeb.FileUpload.file_upload/1
    ...

And that line (in my case, lib/my_app_web/live/components/forms/inputs/file_upload.ex:42) directly maps to my live_img_preview/2 call:

<%= live_img_preview(entry, class: preview_size(@size)) %>

The error doesn't make a lot of sense, but it is telling you what the problem is - you're calling a function component, but not in the right way.

In earlier versions of LiveView, that was the right way to render an image preview. However, in 0.18.0, that function has been "deprecated", and as of 0.18.1, gone entirely.

Luckily it's a simple fix - convert any call to live_img_preview/2 to its function component form:

<.live_img_preview entry={entry} class={preview_size(@size)} />

And presto, everything works again. โœจ

And with that, my app upgrade to Phoenix LiveView 0.18 is complete - I hope this helps anyone that might get stuck where I did!

โ† Home

Want to talk tech on Twitter? You can find me at @sevenseacat!

Built using 11ty and TailwindCSS.