Search code examples
angularangular-cdk

ExpressionChangedAfterItHasBeenCheckedError thrown on change detection when TemplatePortal attached to parents PortalOutlet


I have the following component structure: App -> GrandParent -> Parent -> Child.

  1. The ChildComponennt declares a <ng-template cdkPortal> in its template.
  2. AppComponent, GrandParentComponent and ParentComponent each declares a <ng-template cdkPortalOutput> in their respective templates.

Now, if the the ChildComponent attaches its portal property:

  • ... to the ParentComponent - everything works as expected. You can update the input[text] and the change nicely propagates down into the TemplatePortal.
  • to the GrandParentComponent - the ExpressionChangedAfterItHasBeenCheckedError is thrown during the first change detection run. Every subsequent update in input[text] results in the same error. The state of the TemplatePortal is "one step behind" (meaning - if I type "abc" into the input, the value in TemplatePortal equals "ab")
  • to the AppComponent - same behaviour as GrandParentComponent except for the initial error.

Stackblitz: https://stackblitz.com/edit/portal-cdk?file=src%2Fapp%2Fchild%2Fchild.component.ts (uncomment calls in ChildComponent#ngOnInit)

Does somebody have an explanation for this behaviour? What would be the proper way to use the CDK's portal to display a TemplatePortal in a PortalOutlet located a couple of components above?

Thanks !


Solution

  • I wasn't able to find solution to your problem and If anyone knows, I'm interested as well, however at least I created workaround for you. It doesn't use cdk-portal, just Angular's viewContainerRef, but I belive cdk-portal uses similar approach.

    Stackblitz: https://stackblitz.com/edit/portal-cdk-uiyxhn (uncomment calls in ChildComponent#ngOnInit)