From 8f368e6e7b7f4b5f8ebbe6a3ec83f8bbf0a000a9 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 5 Dec 2025 14:09:32 +0100 Subject: [PATCH] fix(cdk/overlay): error when attempting to attach disposed overlay Fixes an error that was being thrown when calling `attach` on an overlay that was disposed already. --- src/cdk/overlay/overlay-ref.ts | 10 ++++++++++ src/cdk/overlay/overlay.spec.ts | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index 000e5ca8576d..ab9bae62f63c 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -51,6 +51,7 @@ export class OverlayRef implements PortalOutlet { private _backdropRef: BackdropRef | null = null; private _detachContentMutationObserver: MutationObserver | undefined; private _detachContentAfterRenderRef: AfterRenderRef | undefined; + private _disposed: boolean; /** * Reference to the parent of the `_host` at the time it was detached. Used to restore @@ -120,6 +121,10 @@ export class OverlayRef implements PortalOutlet { * @returns The portal attachment result. */ attach(portal: Portal): any { + if (this._disposed) { + return null; + } + // Insert the host into the DOM before attaching the portal, otherwise // the animations module will skip animations on repeat attachments. this._attachHost(); @@ -240,6 +245,10 @@ export class OverlayRef implements PortalOutlet { /** Cleans up the overlay from the DOM. */ dispose(): void { + if (this._disposed) { + return; + } + const isAttached = this.hasAttached(); if (this._positionStrategy) { @@ -266,6 +275,7 @@ export class OverlayRef implements PortalOutlet { this._detachments.complete(); this._completeDetachContent(); + this._disposed = true; } /** Whether the overlay has attached content. */ diff --git a/src/cdk/overlay/overlay.spec.ts b/src/cdk/overlay/overlay.spec.ts index 400a7d9a9285..c2c0ac0aebd5 100644 --- a/src/cdk/overlay/overlay.spec.ts +++ b/src/cdk/overlay/overlay.spec.ts @@ -495,6 +495,13 @@ describe('Overlay', () => { expect(paneElement.childNodes.length).toBe(0); })); + it('should do nothing when trying to attach a disposed overlay', () => { + const overlayRef = createOverlayRef(injector); + overlayRef.dispose(); + overlayRef.attach(componentPortal); + expect(document.querySelector('.cdk-overlay-pane')).toBeFalsy(); + }); + describe('positioning', () => { let config: OverlayConfig;