From 9ce67f66597b99dd2f73d1390f48f09fc3ec3153 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sun, 21 Jan 2018 16:49:04 +0100 Subject: [PATCH] fix(overlay): attempting to position overlay if it was detached immediately after being attached Adds a check that ensures that the `OverlayRef` doesn't attempt to position itself if it was detached before the zone managed to stabilize. This manifested itself as an issue in the select where it could end up throwing an error, because the relevant nodes are no longer in the DOM. Fixes #9406. --- src/cdk/overlay/overlay-ref.ts | 5 ++++- src/cdk/overlay/overlay.spec.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index c1be7f8b78b2..6105440173a1 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -82,7 +82,10 @@ export class OverlayRef implements PortalOutlet { // before attempting to position it, as the position may depend on the size of the rendered // content. this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => { - this.updatePosition(); + // The overlay could've been detached before the zone has stabilized. + if (this.hasAttached()) { + this.updatePosition(); + } }); // Enable pointer events for the overlay pane element. diff --git a/src/cdk/overlay/overlay.spec.ts b/src/cdk/overlay/overlay.spec.ts index 01fc5400ed3a..a8302dbb9c42 100644 --- a/src/cdk/overlay/overlay.spec.ts +++ b/src/cdk/overlay/overlay.spec.ts @@ -255,6 +255,22 @@ describe('Overlay', () => { expect(overlayContainerElement.querySelectorAll('.fake-positioned').length).toBe(1); })); + + it('should not apply the position if it detaches before the zone stabilizes', fakeAsync(() => { + config.positionStrategy = new FakePositionStrategy(); + + const overlayRef = overlay.create(config); + + spyOn(config.positionStrategy, 'apply'); + + overlayRef.attach(componentPortal); + overlayRef.detach(); + viewContainerFixture.detectChanges(); + tick(); + + expect(config.positionStrategy.apply).not.toHaveBeenCalled(); + })); + }); describe('size', () => {