Skip to content

[bug] Cancel drag from the outside / Cannot read properties of null (reading 'Sortable..') in _emulateDragOver #2307

@Kasheftin

Description

@Kasheftin

Repro & Source Code
Here's the repro: https://kasheftin.github.io/vuedraggable-bug/
Here's the source code: https://github.com/Kasheftin/vuedraggable-bug

Versions
sortablejs = ^1.15.0
@types/sortablejs = ^1.15.1
vuedraggable = ^4.1.0

Repro steps

  1. Go to https://kasheftin.github.io/vuedraggable-bug/.
  2. Click on the "blink" button. This button adds a temporary item to the list. The item is removed after 5 seconds.
  3. Start dragging the created item to the other column but don't mouse up, just hold it.
  4. Wait 5 seconds until the source element is removed.
  5. Console starts spamming messages like Uncaught TypeError: Cannot read properties of null (reading 'Sortable1692890267221')
  6. Mouse Up.
  7. Fake (non-existent) item is being readded to the list. There's a store vs. DOM tree resynchronization (not sure about this step, it might be vuedraggable@next bug).

Demo
Peek 2023-08-24 18-33

Motivation / Real-world example
We are developing a real-time application. Imagine some kind of kanban board that is used by multiple users at the same time. One user can start dragging a card while another user might delete it. In this case, we get several errors related both to sortable.js and vuedraggable. Sortable.js bug is definitely the repro step №5. We use forceFallback option, and the bug happens in _emulateDragOver function while trying to evaluate dragEl.parentNode[expando]._isOutsideThisEl(target). It looks like dragEl is detached from the DOM, and it has parentNode=null.

However, our main goal here is to be able to cancel the drag. If some item is being dragged while another user deletes it, we want the drag to stop. I tried to set disabled prop to true temporary, but it does not work, a ghost item still follows the cursor. Obviously, it's not related to any checks in move and other events, because it's something that happens from the outside. The socket receives the message about item deletion, the item is removed from the store, it matches the currently dragged item.id, hence we have to trigger some cancel method in sortable.js which removes the ghost item and stops the drag logic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions