From 6fdc2371b014cd1d9058eaae529a6a8f5f96ca55 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 2 Nov 2017 04:32:06 +0100 Subject: [PATCH] fix(overlay): emitting to detachments stream when not attached (#7944) Currently the `detachments` stream will emit any time the `detach` or `dispose` methods are called, which doesn't reflect actual detachments. It is something I noticed while looking into #7922. --- src/cdk/overlay/overlay-ref.ts | 12 +++++++++++- src/cdk/overlay/overlay.spec.ts | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index 0f36b2a0ae7..c5b71dee498 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -103,6 +103,10 @@ export class OverlayRef implements PortalOutlet { * @returns The portal detachment result. */ detach(): any { + if (!this.hasAttached()) { + return; + } + this.detachBackdrop(); // When the overlay is detached, the pane element should disable pointer events. @@ -133,6 +137,8 @@ export class OverlayRef implements PortalOutlet { * Cleans up the overlay from the DOM. */ dispose(): void { + const isAttached = this.hasAttached(); + if (this._config.positionStrategy) { this._config.positionStrategy.dispose(); } @@ -145,7 +151,11 @@ export class OverlayRef implements PortalOutlet { this._portalOutlet.dispose(); this._attachments.complete(); this._backdropClick.complete(); - this._detachments.next(); + + if (isAttached) { + this._detachments.next(); + } + this._detachments.complete(); } diff --git a/src/cdk/overlay/overlay.spec.ts b/src/cdk/overlay/overlay.spec.ts index d15dd68c5e5..2ea9ae873fa 100644 --- a/src/cdk/overlay/overlay.spec.ts +++ b/src/cdk/overlay/overlay.spec.ts @@ -177,6 +177,26 @@ describe('Overlay', () => { expect(spy).toHaveBeenCalled(); }); + it('should not emit to the detach stream if the overlay has not been attached', () => { + let overlayRef = overlay.create(); + let spy = jasmine.createSpy('detachments spy'); + + overlayRef.detachments().subscribe(spy); + overlayRef.detach(); + + expect(spy).not.toHaveBeenCalled(); + }); + + it('should not emit to the detach stream on dispose if the overlay was not attached', () => { + let overlayRef = overlay.create(); + let spy = jasmine.createSpy('detachments spy'); + + overlayRef.detachments().subscribe(spy); + overlayRef.dispose(); + + expect(spy).not.toHaveBeenCalled(); + }); + it('should emit the detachment event after the overlay is removed from the DOM', () => { let overlayRef = overlay.create();