Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS client crashes when submitting a form that results in switching the underlying LiveView instance #3068

Open
DaTrader opened this issue Jan 31, 2024 · 11 comments

Comments

@DaTrader
Copy link

Environment

  • Elixir version (elixir -v): 1.14.4
  • Phoenix version (mix deps): 1.7.10
  • Phoenix LiveView version (mix deps): 0.20.3+ (commit: 66d38cf704f51231ac69098a220fa4760d0cb0b9)
  • Operating system: Linux Mint
  • Browsers you attempted to reproduce this bug on (the more the merrier): FF, Chrome
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: Yes

Actual behavior

Important:

  • The bug manifests "only" on Chrome and not on Firefox.
  • The bug was introduced after the LV version 0.20.1 as it does not manifest there

In a LiveView instance, one of its live components opens an option list form (another live component) that submits the user-selected item(s) to the live component that opened it. Once received and interpreted the form data, the live component that opened the form live component navigates to a route that results in switching the current LiveView instance with another one.

On the JS client the last JSON object received prior to JS crashing is the update of the form that submitted the data. Then the following error occurs:

rendered.js:313 Uncaught TypeError: Cannot read properties of undefined (reading '0')
    at Rendered.toOutputBuffer (rendered.js:313:22)
    at Rendered.recursiveToString (rendered.js:145:10)
    at Rendered.recursiveCIDToString (rendered.js:407:32)
    at Rendered.componentToString (rendered.js:265:31)
    at View.componentPatch (view.js:551:41)
    at view.js:523:19
    at Set.forEach (<anonymous>)
    at view.js:522:20
    at LiveSocket.time (live_socket.js:259:59)
    at View.update (view.js:520:23)

Following the error, the target route page JSON object is received and rendered properly. Given the circumstances (having the LiveView instance switched) the app continues to run normally.

Expected behavior

The JS client should not crash on Chrome (as it does not crash on Firefox) when the underlying LiveView instance is being switched while the update of the (most probably) no-longer existing form is received.

@chrismccord
Copy link
Member

Have you tried to reproduce this on the latest main? We had several bug fixes wrt to live components and this may already be fixed. Thanks!

@DaTrader
Copy link
Author

Just did. Unfortunately, the bug is still there.

@DaTrader
Copy link
Author

If it's of help, tomorrow I can try pinpoint the exact commit when the bug was introduced.

@chrismccord
Copy link
Member

chrismccord commented Jan 31, 2024

We'll need a minimal reproduction to be able to look at this one as it involves a lot of moving pieces. Thanks!

@DaTrader
Copy link
Author

DaTrader commented Feb 1, 2024

I'll see what I can do.

@marschro
Copy link

marschro commented Feb 4, 2024

Hi there,
I just wanted to file a bug, but this sounds a bit like what I experience.

  • Affected Version 0.20.4
  • All fine with Version 0.20.3 - so it must be a change there.

Error in browser console:

dom.js:305 Uncaught TypeError: Cannot read properties of null (reading 'elements')
    at dom.js:305:23
    at Set.forEach (<anonymous>)
    at Object.maybeHideFeedback (dom.js:304:11)
    at DOMPatch.perform (dom_patch.js:295:9)
    at View.performPatch (view.js:442:11)
    at view.js:548:33
    at LiveSocket.time (live_socket.js:259:59)
    at View.update (view.js:545:23)
    at view.js:600:56
    at Array.forEach (<anonymous>)

When happens the client side javascript error?

  1. A LiveView that contains a table of items
  2. Clicking on one of the items, the edit form is displayed.
  3. While the form of the item is displayed, the user can click another item in the table which should update the current displayed form with the data of the now clicked item.
  4. But doing that crashes the dom_patch.js (error above). one has to reload the page to resurrect.

@marschro
Copy link

marschro commented Feb 4, 2024

I try will reproduce in a small setup...

@SteffenDE
Copy link
Collaborator

@marschro I think your issue is already solved on main

@marschro
Copy link

marschro commented Feb 4, 2024

Ah, thanks, @SteffenDE - I'll check - thought already I can contribute anything useful ;-)

@DaTrader
Copy link
Author

DaTrader commented Feb 6, 2024

@chrismccord I've found where the bug is while reducing the app to the minimum. Haven't finished it yet but since I need to spend more hours to complete it, I need to ask you first if the following description can give you enough clue to pinpoint and fix the bug without the demo app.

  1. Scrap the whole description of the bug I initially provided. It's all true, but other than the error in the Chrome web console, it seems to be irrelevant.

  2. The problem is when there's an element without an id but has a phx-mounted set to JS.show together in the same LiveView instance page with a LiveComponent that contains a stream (and loads asynchronously into it, although not sure if async loading matters) and that's getting updated by the LV instance via one of its parameters (e.g. when received user-selected items from another component).

That element without id may be a button such as the one below:

<button 
  type="button" phx-click="show_config" 
  phx-mounted={JS.show( transition: {"delay-500 ease-out duration-150", "opacity-0", "opacity-100"}, time: 650)}
>
  My button
</button>

All it takes to circumvent the bug is to add an id to the button (or remove the phx-mounted attribute).

@jbosse
Copy link

jbosse commented Feb 7, 2024

@marschro I think your issue is already solved on main

Thanks @SteffenDE. Yes it looks like Chris committed a fix for the bug I was having, the same as @marschro. I am wondering if it is possible to get a sense of when 0.20.5 would be tagged. It feels like "when its ready" is the vibe, which is totally fine, I just don't love having to go to production pointing my dependencies to a commit hash in main if I can avoid it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants