Phoenix_live_view: Duplicate child no longer raises

Created on 16 May 2019  路  6Comments  路  Source: phoenixframework/phoenix_live_view

Hey folks, I'm trying to do a live_render within a for comprehension where each item shows the time ago in words from a specific point in time. I've created an isolated example that I include here that shows the issue. Only the first item in the list re-renders on each tick.

Environment

  • Elixir version (elixir -v):
Erlang/OTP 21 [erts-10.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Elixir 1.8.1 (compiled with Erlang/OTP 21)
  • Phoenix version (mix deps):
$ mix deps|grep phoenix
* phoenix_pubsub 1.1.2 (Hex package) (mix)
  locked at 1.1.2 (phoenix_pubsub) 496c303b
* phoenix_html 2.13.2 (Hex package) (mix)
  locked at 2.13.2 (phoenix_html) f5d27c9b
* phoenix 1.4.4 (Hex package) (mix)
  locked at 1.4.4 (phoenix) 5d9a0e2c
* phoenix_live_view 0.1.0 (https://github.com/cargosense/phoenix_live_view.git) (mix)
  • NodeJS version (node -v):
    v10.4.1
  • NPM version (npm -v):
    6.1.0
  • Operating system: OS X

Actual behavior

image

defmodule Ago do
  use Phoenix.LiveView

  def render(assigns) do
    ~L"<%= @duration %>"
  end

  def mount(%{time: time}, socket) do
    if connected?(socket) do
      :timer.send_interval(1000, self(), :tick)
    end

    socket =
      socket
      |> assign(:time, time)
      |> assign_duration

    {:ok, socket}
  end

  def handle_info(:tick, socket) do
    IO.puts("ticking")
    {:noreply, assign_duration(socket)}
  end

  defp assign_duration(socket) do
    duration = Timex.from_now(socket.assigns.time)
    assign(socket, :duration, duration)
  end
end


defmodule Counter do
  use Phoenix.LiveView

  def render(assigns) do
    ~L"""
    <%= for i <- @things do %>
      <p>Computed in child: <%= live_render(@socket, Ago, session: %{time: @rendered_at}) %></p>
    <% end %>
    """
  end

  def mount(_, socket) do
    socket =
      socket
      |> assign(:rendered_at, DateTime.utc_now())
      |> assign(:things, [1, 2, 3])

    {:ok, socket}
  end
end

Expected behavior

Each child live_render counts backwards.

bug

All 6 comments

You need to pass the child_id option to de-duplicate the children. We are supposed to raise in these cases, but it seems we have had a regression in our duplicate child detection. This will work:

    <%= for i <- @things do %>
      <p>Computed in child: <%= live_render(@socket, Ago, session: %{time: @rendered_at}, child_id: "ago#{i}") %></p>
    <% end %>

Keeping this open so we can fix the error. Thanks!

@alexgaribay lmk if you'd like to grab this one <3

Yep. I鈥檒l take a look.

Confirmed that adding a child_id fixes the issue.

What would the downside to making the default be :erlang.unique_integer ?

This is no longer relevant on a branch we will be soon merging. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tfwright picture tfwright  路  3Comments

jamilabreu picture jamilabreu  路  5Comments

josevalim picture josevalim  路  3Comments

lukegalea picture lukegalea  路  3Comments

alexgaribay picture alexgaribay  路  4Comments