Skip to content

bug(CdkDragDrop): cdkDropList silently breaks with ngFor over calculated expression #21682

@amdw

Description

@amdw

If a cdkDropList is based on a collection that is not a direct member of the component (such as a method on the component that returns an array), the drag-and-drop behaviour does not work.

Reproduction

https://stackblitz.com/github/amdw/drag-drop-repro

There are three drop-lists in this project, all intended to modify the same underlying words array. The first and the last work as expected; the middle one (where the *ngFor is over a calculated expression displayedWords()) does not.

Expected Behavior

I would expect drag-and-drop in the middle drop-list to work in exactly the same as the first and the last one, changing the order of the words in all three lists.

Failing that, I would at least expect to see a compile error here, or a warning on the JavaScript console, or (at a very minimum) clear and prominent warnings in the documentation that drop-lists won't work if they are based on calculated expressions.

Since the programmer has taken explicit responsibility (via a cdkDropListDropped function) for applying the appropriate update to the underlying data structure when list items are dragged and dropped, I don't see any reason in principle why this shouldn't work.

In the last drop-list, this is addressed by converting the list source into a member on the component. However, this requires the programmer to manually update that member whenever the underlying words array changes. This is inconvenient and error-prone, and undermines the automated data flow and change detection which is a key benefit of Angular.

Actual Behavior

The top and bottom drop-lists work as expected (items can be dragged and dropped, and this updates the underlying words array, causing the order of words in all three cards to change). However, dragging and dropping in the middle card has no effect whatsoever. It's as if it wasn't a cdkDropList at all.

There are no compile errors or warnings, or JavaScript console messages warning that something might be wrong. The intended drop-list just silently doesn't work.

I don't see anything in the documentation that states that this type of pattern should not work.

Environment

  • Angular: 11.1.0
  • CDK/Material: 11.1.0
  • Browser(s): Reproduced on Firefox 84.0.2 on Ubuntu and Chrome 87.0.4280.141 on MacOS

Possibly related issues

This issue may be the same as #13340 - I'm not sure, as the wording of that issue is not clear to me. That issue is marked as a feature request, whereas I would regard this as a bug, or at least a surprising undocumented limitation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions