Encountered a weird scenario with LiveView where dom nodes disappear, am I missing something?

A reproduction of the issue on top of a fresh live phoenix project exists here https://github.com/wittjosiah/live-div-poof/commit/b9809cb550f6630f777d3a4ee0ee095442d32253

As noted:

If a live component is rendered above nested divs with ids with
phx-update=ignore the inner div disappear when the socket connects.

Removing the live component, either of the ids, or phx-update=ignore causes the
issue not to occur.

The markup added is simply

<%= live_component @socket, LiveDivPoof.Component, id: "component" %>

<section class="phx-hero">
  <div id="parent" phx-update="ignore">
    <div id="myDiv">Bye bye Div</div>

where Component is a minimal live component which does nothing.

I’m trying to figure out if I’m missing something here about why this is happening or if there’s a LiveView bug related to phx-update=ignore. Any help is much appreciated!

1 Like

Not an expert on this, but some additional information may help.

TL;DR; As long as you remove the id attribute of this node: <div id="myDiv">...</div>
the bug disappears.

The furthest clue I can see is that this DOM node was attached to a new parent (id="parent") which is not in the document DOM tree and only lives in memory. It’s still there, but out of vision.

The logic happens here:

where currChild and currChild.parentNode are both newly created DOM in memory, whilst unmatchedFromEl is the original node (div#myDiv) in the DOM tree, in sight. After execution of this line, unmatchedFromEl (or the div#myDiv in sight), will disappear due to the replacement.

It seems like a bug but I don’t understand the logic here. Maybe someone of the LiveView core team can give more details on it.

This may not the right way to solve, but can be used to avoid the logic happening:
Simply not to use id attributes in nodes who are direct children of a node with “phx-update” attribute.

I believe there must be some better way to fix it, though.

Thanks for providing more context to what’s going on, confirms I’m not going crazy!

I did notice that removing the ids from the child nodes stops this from happening, unfortunately for my current use case there’s a library which is using those ids to mount iframes into the DOM. After reproducing the minimal case however I did notice that removing the id from the parent also seemed to stop this from happening and that id wasn’t actually needed in my case. So for the time being I’ve been able to work around this issue!

Would definitely be interesting to hear from someone on the LiveView team as to whether this is known or unexpected behaviour though.

I’m working on a fix on the LV side. It appears to be a bug in morphdom, but it may be something we’re doing with ignored containers. We disallow patching ignored containers, but it appears that morphdom will fire our element updated callback when it knows the element was already removed. I have a local fix in LV that works around this issue, but I need to check with Scott to see if we can address in morphdom. Thanks!