{"record":{"id":"2d209a50351c85b6","repo":"angular/components","slug":"cannot-attach-component-portal-to-outlet-without-a","errorCode":null,"errorMessage":"Cannot attach component portal to outlet without an ApplicationRef.","messagePattern":"Cannot attach component portal to outlet without an ApplicationRef\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cdk/portal/dom-portal-outlet.ts","lineNumber":69,"sourceCode":"    // When the ViewContainerRef is missing, we use the factory to create the component directly\n    // and then manually attach the view to the application.\n    if (portal.viewContainerRef) {\n      const injector = portal.injector || portal.viewContainerRef.injector;\n      const ngModuleRef = injector.get(NgModuleRef, null, {optional: true}) || undefined;\n\n      componentRef = portal.viewContainerRef.createComponent(portal.component, {\n        index: portal.viewContainerRef.length,\n        injector,\n        ngModuleRef,\n        projectableNodes: portal.projectableNodes || undefined,\n        bindings: portal.bindings || undefined,\n        directives: portal.directives || undefined,\n      });\n\n      this.setDisposeFn(() => componentRef.destroy());\n    } else {\n      if ((typeof ngDevMode === 'undefined' || ngDevMode) && !this._appRef) {\n        throw Error('Cannot attach component portal to outlet without an ApplicationRef.');\n      }\n      const appRef = this._appRef!;\n\n      const elementInjector = portal.injector || this._defaultInjector || Injector.NULL;\n      const environmentInjector = elementInjector.get(EnvironmentInjector, appRef.injector);\n      componentRef = createComponent(portal.component, {\n        elementInjector,\n        environmentInjector,\n        projectableNodes: portal.projectableNodes || undefined,\n        bindings: portal.bindings || undefined,\n        directives: portal.directives || undefined,\n      });\n\n      appRef.attachView(componentRef.hostView);\n      this.setDisposeFn(() => {\n        // Verify that the ApplicationRef has registered views before trying to detach a host view.\n        // This check also protects the `detachView` from being called on a destroyed ApplicationRef.\n        if (appRef.viewCount > 0) {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/portal/dom-portal-outlet.ts#L51-L87","documentation":"BasePortalOutlet/DomPortalOutlet can attach a ComponentPortal only if it has an ApplicationRef (needed to create and run change detection for the component). When the outlet was constructed without an ApplicationRef (only an injector/viewContainerRef) and the portal is a ComponentPortal, this dev-mode check throws.","triggerScenarios":"Calling `outlet.attachComponentPortal(portal)` on a DomPortalOutlet constructed as `new DomPortalOutlet(hostEl, injector, null, doc)` (no ApplicationRef), or on a CdkPortalOutlet in a context with no ApplicationRef available.","commonSituations":"Manually constructing DomPortalOutlet for dynamic UI (tooltips, dialogs) and passing undefined for the ApplicationRef parameter; migrating Angular versions where createComponent requires an EnvironmentInjector/ApplicationRef; using the outlet purely for DOM/Template portals then switching to a ComponentPortal.","solutions":["Pass an ApplicationRef when constructing the outlet: `new DomPortalOutlet(host, injector, injector.get(ApplicationRef), injector.get(DOCUMENT))`","Attach a TemplatePortal or DomPortal instead if you only need DOM content","Use a ViewContainerRef-based outlet (CdkPortalOutlet directive) which can create components without ApplicationRef","Ensure your DI environment resolves ApplicationRef (not outside Angular's injector)"],"exampleFix":"// before\nconst outlet = new DomPortalOutlet(hostEl, injector, undefined, document);\noutlet.attachComponentPortal(new ComponentPortal(MyComp)); // throws\n// after\nconst appRef = injector.get(ApplicationRef);\nconst outlet = new DomPortalOutlet(hostEl, injector, appRef, document);\noutlet.attachComponentPortal(new ComponentPortal(MyComp));","handlingStrategy":"validation","validationCode":"const appRef = injector.get(ApplicationRef, null);\nif (appRef) {\n  const outlet = new DomPortalOutlet(host, injector, appRef, injector.get(DOCUMENT));\n  outlet.attachComponentPortal(portal);\n}","typeGuard":"function supportsComponentPortals(outlet: DomPortalOutlet): boolean {\n  return (outlet as unknown as {_appRef?: unknown})._appRef != null;\n}","tryCatchPattern":"try {\n  outlet.attachComponentPortal(portal);\n} catch (e) {\n  if (e.message.includes('without an ApplicationRef')) {\n    outlet.attachTemplatePortal(new TemplatePortal(tpl, vcr)); // fallback to template portal\n  } else { throw e; }\n}","preventionTips":["Always pass ApplicationRef when constructing DomPortalOutlet manually","Get it via injector.get(ApplicationRef) rather than hardcoding undefined","If you cannot supply ApplicationRef, restrict the outlet to TemplatePortal/DomPortal","Prefer CdkPortalOutlet directive or ViewContainerRef.createEmbeddedView for component hosting"],"tags":["angular","cdk","portal","dependency-injection"],"backgroundTag":"missing-applicationref","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}