Liveview is not updating

I have a LiveComponent that builds a <table> from a map.
Everything worked fine until I removed an IO.inspect from the beginning of the heredoc.
Now I don’t get updates (the first time the component is rendered, but not when its changed). If I put the inspect back in everything works… :face_with_monocle:

~L"""
  <% IO.inspect m %> <---- when I take this away: no more updates
  <%= for {_k, v} <- m do %>
    <%= inspect v %>
  <% end %>
"""

Maybe change your for loop inspect to:
<%= IO.inspect v %>

What if you store m as an assign? I seem to recall something about variables not being change-tracked like assigns are.

3 Likes

that would output the inspect into the html.

I’m calling the component with an ID of the thing I want to display, this ID and the list of all those things are in the components assigns, sth like:

def render(%{display_this: id, all_the_things: things} = assigns) do
  {m, related_thing} = get_info(id, things)

Putting the thing into the assigns would take away work from the component that belongs there.

It seems like if I do anything else with the map (like <%= m.field %>) inside the table it works. If I only access the map in the loop, there are no updates. :thinking:

Is get_info a pure function? I mean, did id or things change?
It is a good discipline to make sure there is nothing but pure functions in the rendering.

yes, the function is pure, the only odd thing I’m doing is, that the maps i grab ID from are not directly in the assings but in another map (state). Here is the full code of the component (omitting the heredoc)

def render(%{selected_param: selected_param, state: state} = assigns) do
    {ref, type} = get_param_info(selected_param, state)

...

def get_param_info(
      ref_id,
      %{
        parameter_refs: parameter_refs,
        parameter_types: parameter_types
      }
    ) do
  ref = Map.get(parameter_refs, ref_id)
  type = Map.get(parameter_types, Map.get(ref, :parameterType))
  {ref, type}
end

Maybe the pin operator? ^,e.g.

~L"""
  <% IO.inspect m %> <---- when I take this away: no more updates
  <%= for {_k, v} <- ^m do %>
    <%= inspect v %>
  <% end %>
"""

thats a compile-error. pin is for matches only.

It seems like what you’re doing is explicitly warned against in the documentation: Live EEx Pitfalls

Similarly, do not define variables at the top of your render function:

Instead explicitly precompute the assign in your LiveView, outside of render:

4 Likes

OK, I really should rtfm. The problem with liveview is, its too simple, everything just works (until now).