Skip to content

Commit 0431d81

Browse files
authored
fix(cdk/drag-drop): error if dragged item is destroyed as a result of the entered event (#22904)
When an item enters a new drop container, we dispatch an event and run some logic afterwards. The problem is that if the item is destroyed as a result of the event, the logic after the event will throw because dragging was interrupted. Fixes #22813.
1 parent d5a5de2 commit 0431d81

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/cdk/drag-drop/directives/drag.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,6 +5447,28 @@ describe('CdkDrag', () => {
54475447
expect(itemEnterEvent).toEqual(expectedEvent);
54485448
}));
54495449

5450+
it('should not throw if dragging was interrupted as a result of the entered event',
5451+
fakeAsync(() => {
5452+
const fixture = createComponent(ConnectedDropZones);
5453+
fixture.detectChanges();
5454+
5455+
const groups = fixture.componentInstance.groupedDragItems;
5456+
const item = groups[0][1];
5457+
const targetRect = groups[1][2].element.nativeElement.getBoundingClientRect();
5458+
5459+
fixture.componentInstance.enteredSpy.and.callFake(() => {
5460+
fixture.componentInstance.todo = [];
5461+
fixture.detectChanges();
5462+
});
5463+
5464+
expect(() => {
5465+
dragElementViaMouse(
5466+
fixture, item.element.nativeElement, targetRect.left + 1, targetRect.top + 1);
5467+
flush();
5468+
fixture.detectChanges();
5469+
}).not.toThrow();
5470+
}));
5471+
54505472
it('should be able to drop into a new container after scrolling into view', fakeAsync(() => {
54515473
const fixture = createComponent(ConnectedDropZones);
54525474
fixture.detectChanges();

src/cdk/drag-drop/drag-ref.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export class DragRef<T = any> {
151151
* Whether the dragging sequence has been started. Doesn't
152152
* necessarily mean that the element has been moved.
153153
*/
154-
private _hasStartedDragging: boolean;
154+
private _hasStartedDragging = false;
155155

156156
/** Whether the element has moved since the user started dragging it. */
157157
private _hasMoved: boolean;
@@ -982,10 +982,13 @@ export class DragRef<T = any> {
982982
});
983983
}
984984

985-
this._dropContainer!._startScrollingIfNecessary(rawX, rawY);
986-
this._dropContainer!._sortItem(this, x, y, this._pointerDirectionDelta);
987-
this._applyPreviewTransform(
988-
x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
985+
// Dragging may have been interrupted as a result of the events above.
986+
if (this.isDragging()) {
987+
this._dropContainer!._startScrollingIfNecessary(rawX, rawY);
988+
this._dropContainer!._sortItem(this, x, y, this._pointerDirectionDelta);
989+
this._applyPreviewTransform(
990+
x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
991+
}
989992
}
990993

991994
/**

0 commit comments

Comments
 (0)