Live updates inside a Phoenix.Component

I built a component based upon Phoenix.Component to wrap up a tab control. It works in a similar way to the table example in the docs.

I use it like this:

  <FaasWeb.Components.Elements.tabs>
    <:tab label="Standard Logs" css={tab_css("Standard Logs", @active_tab)}>
      <pre>
        <%= render_logs(@execution, :standard) %>
      </pre>
    </:tab>
    <:tab label="Error Logs" css={tab_css("Error Logs", @active_tab)}>
      <pre>
        <%= render_logs(@execution, :error) %>
      </pre>
    </:tab>
    <:tab label="Comments" css={tab_css("Comments", @active_tab)}>
      <%= if handle_field(@execution.comments) do %>
        <pre><%= @execution.comments %></pre>
      <% else %>
        <pre>No Comments Recorded</pre>
      <% end %>
    </:tab>
  </FaasWeb.Components.Elements.tabs>

The component is really simple, just wrapping up the HTML around tabbed controls:

  def tabs(assigns) do
    ~H"""
      <div class="tabs is-centered is-boxed">
        <ul>
          <%= for tab <- @tab do %>
            <li class={tab_css(tab)}>
              <a phx-click="navigate_tab" phx-value-tab={tab.label}><%= tab.label %></a>
            </li>
          <% end %>
        </ul>
      </div>

      <div class="">
        <%= for tab <- @tab do %>
          <div class={tab_content_class(tab)}>
            <%= render_slot(tab) %>
          </div>
        <% end %>
      </div>
    """
  end

The Execution model has a property called logs which is backed by a JSON column, so that is a map.

I have the system setup such that DB touches in the context event back to the UI for update. For other parts of the UI things re-render as expected. However the logs do not. I can see the update event in the live view code but the HTML doesn’t change.

I have placed a div on the page that looks like:

<%= @execution.logs["out"] %>

And it also doesn’t update. When the page is first rendered @execution.logs will be nil and following a background update will be %{err: "", out: "some string"}.

I don’t understand what I have done wrong here.

1 Like

I am a bit of a bozo. There isn’t anything wrong with my component or how I have setup things here. My issue is that I have a map of %{out: "", err: ""} and I was trying to reach into that using "out". Updating things to use atoms has updates working as expected.

1 Like