Softknobs

Softknobs

Phoenix.Router.NoRouteError on existing file

Hi,

I am trying to create a crud Liveview 0.19.5 program created from the Phoenix 1.7.7 template. Most code was generated by phoenix and ecto from the command line, so it is the default CRUD form with Master/Detail view that I am using.

The CRUD Master/Detail form worked well until I added a file upload to the detail form. The uploaded image is uploaded, the problem is that I get a Phoenix.Router.NoRouteError in the master form when trying to display a thumbnail of the uploaded image. So after saving, the detail form (livecomponent) is hidden and I get this:


The two broken images come from the form:
The form is (generated from command line, adapted to show the image):

<.table
  id="tags"
  rows={@streams.tags}
  row_click={fn {_id, tag} -> JS.navigate(~p"/tags/#{tag}") end}
>
  <:col :let={{_id, tag}} label="Tag"><%= tag.tag_id %></:col>
  <:col :let={{_id, tag}} label="Image url"><img src={tag.image_url} width="50" /></:col>
  <:col :let={{_id, tag}} label="Name"><%= tag.name %></:col>
  <:col :let={{_id, tag}} label="Volume"><%= tag.volume %></:col>
  <:action :let={{_id, tag}}>
    <div class="sr-only">
      <.link navigate={~p"/tags/#{tag}"}>Show</.link>
    </div>
    <.link patch={~p"/tags/#{tag}/edit"}>Edit</.link>
  </:action>
  <:action :let={{id, tag}}>
    <.link
      phx-click={JS.push("delete", value: %{id: tag.id}) |> hide("##{id}")}
      data-confirm="Are you sure?"
    >
      Delete
    </.link>
  </:action>
</.table>

and also from a “non stream” source (the first broken image displayed) , as I am not familiar with streams yet:

<%= for tag <- @tags do %>
  <img src={tag.image_url} width="50" />
<% end %>

The code used to upload the image in the detail form is:

index.ex (liveview)

  def handle_event("save", %{"tag" => tag_params}, socket) do
    entry_urls =
      consume_uploaded_entries(socket, :image, fn %{path: path}, _entry ->
        dest = Path.join("priv/static/uploads", Path.basename(path))
        File.cp!(path, dest)
        {:ok, Routes.static_path(socket, "/uploads/#{Path.basename(dest)}")}
      end)
    tag_params =
      case entry_urls do
        [url] -> tag_params |> Map.put("image_url", url)
        _ -> tag_params
      end
    save_tag(socket, socket.assigns.action, tag_params)
  end

Save tag saves the data and notifies the parent liveview:
form_component.ex (livecomponent):

  defp save_tag(socket, :edit, tag_params) do
    case Player.update_tag(socket.assigns.tag, tag_params) do
      {:ok, tag} ->
        notify_parent({:saved, tag})

        {:noreply,
         socket
         |> put_flash(:info, "Tag updated successfully")
         |> push_patch(to: socket.assigns.patch)}
#         |> push_navigate(to: "/tags", replace: true)}

      {:error, %Ecto.Changeset{} = changeset} ->
        {:noreply, assign_form(socket, changeset)}
    end
  end

Notify parent is an helper function that is generated:

defp notify_parent(msg), do: send(self(), {__MODULE__, msg})

The code called is then

  @impl true
  def handle_info({RfidPlayerWeb.TagLive.FormComponent, {:saved, tag}}, socket) do
    socket  =
      socket|> assign(:tags, Player.list_tags())
    {:noreply, stream_insert(socket, :tags, tag)}
  end

In my case, data is updated correctly, and the image exists on the server. Actually, the image is displayed if I use F5 to refresh:

Though, if I edit, without changing the image, I get a different behaviour from the “streams” version and this one:

<%= for tag <- @tags do %>
  <img src={tag.image_url} width="50" />
<% end %>

After editing (i.e. going through the “save” event above and the liveview notification) the image will be displayed. The table using streams, will still show the broken image, unless I refresh the page with F5.

I don’t understand what is going wrong. In courses I have dealing with uploads, PubSub is used to update the liveview, so I can’t compare with my own code.

From what I see, the image is there but not found by the router in some situations. It is not a matter of time to copy the file to the uploads folder: I added a timer and the result is the same, moreover if I edit the record again, the image is displayed by the “non stream” version of the code.
I also tried push_navigate but the result is the same. I don’t understand what is happening here.

Sorry for the long post, could not find a way to explain everthing this in a more compact way.

Thanks.

Where Next?

Popular in Questions Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
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

Other popular topics Top

AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
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
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement