phoenix_live_view icon indicating copy to clipboard operation
phoenix_live_view copied to clipboard

Client-side js crashes when component with `phx-remove` set to `JS.hide` navigates to another LiveView

Open DaTrader opened this issue 1 year ago • 6 comments

Environment

  • Elixir version (elixir -v): 1.14.4
  • Phoenix version (mix deps): 1.7.11
  • Phoenix LiveView version (mix deps): 0.20.9 (detected all the way back to 0.20.0 - the oldest I can compile with without errors)
  • 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

Setup

LiveView1 has a function component that conditionally renders an element with a child LiveComponent1.1 that switches to LiveView2 on a button click. The conditionally rendered element has the phx-remove set to a JS.hide with a transition.

<div
  :if={@load?}
  role="dialog"
  aria-modal="true"
  phx-remove={
    JS.hide(
      to: "#Content-#{ @id}",
      transition: { "transition ease-in-out duration-150", "opacity-100 scale-100", "opacity-0 scale-[85%]"}
    )
  }
>

Bug reproducing interaction

  1. LiveView1: click on a button to conditionally render the element with the phx-remove that contains LiveComponent1.1
  2. LiveComponent1.1: click to switch/navigate to LiveView2
  3. LiveComponent2.1 in LiveView2: click to open (instantiate) LiveView1 again
  4. repeat from the beginning

Notes:

  • The JS client crashes in point 2. in a second and all subsequent turns, but never in the first turn.
  • There can be more instances of LiveComponent2.1, but the bug manifests only when clicked on the same instance for the second time (same as in with the same module and ID)
  • It makes no difference if the element with the phx-remove has an id or not.

Without the phx-remove, it all works.

Chrome web console crash message

rendered.js:200 Uncaught TypeError: Cannot read properties of undefined (reading 's')
    at Rendered.cachedFindComponent (rendered.js:200:16)
    at Rendered.mergeDiff (rendered.js:177:26)
    at View.update (view.js:531:19)
    at view.js:625:68
    at View.applyDiff (view.js:266:5)
    at view.js:625:14
    at TransitionSet.flushPendingOps (live_socket.js:963:7)
    at TransitionSet.flushPendingOps (live_socket.js:964:12)
    at live_socket.js:950:12

Firefox web console crash message

Uncaught TypeError: tdiff is undefined
    cachedFindComponent http://localhost:4000/assets/app.js:3925
    mergeDiff http://localhost:4000/assets/app.js:3905
    update http://localhost:4000/assets/app.js:4587
    bindChannel http://localhost:4000/assets/app.js:4677
    applyDiff http://localhost:4000/assets/app.js:4340
    bindChannel http://localhost:4000/assets/app.js:4677
    flushPendingOps http://localhost:4000/assets/app.js:6116
    flushPendingOps http://localhost:4000/assets/app.js:6117
    timer http://localhost:4000/assets/app.js:6100
    setTimeout handler*addTransition http://localhost:4000/assets/app.js:6097
    transition http://localhost:4000/assets/app.js:5438
    transition http://localhost:4000/assets/app.js:4316
    toggle http://localhost:4000/assets/app.js:1800
    hide http://localhost:4000/assets/app.js:1783
    exec_hide http://localhost:4000/assets/app.js:1768
    exec http://localhost:4000/assets/app.js:1659
    exec http://localhost:4000/assets/app.js:1658
    exec http://localhost:4000/assets/app.js:1653
    execJS http://localhost:4000/assets/app.js:5394
    owner http://localhost:4000/assets/app.js:5598
    execJS http://localhost:4000/assets/app.js:5394
    transitionRemoves http://localhost:4000/assets/app.js:5584
    transitionRemoves http://localhost:4000/assets/app.js:5583
    transitionPendingRemoves http://localhost:4000/assets/app.js:3715
    perform http://localhost:4000/assets/app.js:3634
    performPatch http://localhost:4000/assets/app.js:4504
    componentPatch http://localhost:4000/assets/app.js:4623
    update http://localhost:4000/assets/app.js:4593
    update http://localhost:4000/assets/app.js:4592
    time http://localhost:4000/assets/app.js:5417
    update http://localhost:4000/assets/app.js:4590
    bindChannel http://localhost:4000/assets/app.js:4677
    applyDiff http://localhost:4000/assets/app.js:4340
    bindChannel http://localhost:4000/assets/app.js:4677
    after http://localhost:4000/assets/app.js:6090
    requestDOMUpdate http://localhost:4000/assets/app.js:5434
    bindChannel http://localhost:4000/assets/app.js:4676
    onChannel http://localhost:4000/assets/app.js:5444
    trigger http://localhost:4000/assets/app.js:566
    onConnMessage http://localhost:4000/assets/app.js:1310
    decode http://localhost:4000/assets/app.js:826
    onConnMessage http://localhost:4000/assets/app.js:1296
    onmessage http://localhost:4000/assets/app.js:1074

DaTrader avatar Feb 27 '24 15:02 DaTrader