title: Why doesn't the file_input in the form on a Phoenix LiveView return a %Plug.Upload{}?
body: <p>I have a form in a Phoenix LiveView that contains a <code>file_input</code>. I want to use it to allow a user to upload an image. I'm having trouble understanding what the form is sending to my backend, and what I can do with it. I expected a %Plug.Upload{} representation of the image file, as described in <a href="https://www.phoenixframework.org/blog/file-uploads" rel="noreferrer">documentation</a>, but instead I just get <code>"[object File]"</code>. </p>
  
  <p>Note that I am not backing the form with a changeset, because I am not using Ecto:</p>
  
  <pre><code>&lt;%= f = form_for :post, "#", phx_submit: :create_post, phx_change: :image_attach, multipart: true %&gt;
    &lt;%= hidden_input f, :user_id, value: @current_user.account_id %&gt;
    &lt;%= textarea f, :message, class: "social-post-box", placeholder: "Something on your mind?" %&gt;
    &lt;div class="post-submit-container"&gt;
      &lt;%= submit "Post", class: "post-submit" %&gt;
      &lt;label for="post_image" class="post-submit-image"&gt;&lt;/label
      &lt;%= file_input f, :image %      
    &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>I have a handler in the LiveView module to handle the submitted form, and when I inspect the image upload I see <code>"[object File]"</code> </p>
  
  <pre><code>def handle_event("create_post", %{"post" =&gt; post_params}, socket) do
    IO.inspect post_params["image"]
    {:noreply, socket}
  end
  </code></pre>
  
  <p>I tried prying at this location so that I could run <code>i post_params["image"]</code>, and it explains that the object is a bitstring, ie just a binary. So it's literally just the text "[object File]", and not even a file at all?</p>
  
  <p>What is it that I am receiving from my form? Why isn't it a <code>%Plug.Upload{}</code>? How can I achieve my goal of saving this image upload to the local filesystem?</p>