Short Answer
I suspect this is due to the lifecycle and lack of templates on the
first render,
You are exactly right. You can simply update your @ViewChild
decorators for your default ng-template references in table.component.ts, to use {static: true}
instead of {static: false}
Updated stackblitz editor view: https://stackblitz.com/edit/stackblitz-starters-co2me9?file=src%2Ftable%2Ftable.component.ts
Updated stackblitz app share link: https://stackblitz-starters-co2me9.stackblitz.io
Long answer: Lifecycle hooks and @ViewChild {static: true/false}
Per the docs, the static: boolean
property of the ViewChild decorator metadata dictates when the view query will be resolved, before (in ngOnInit
) or after change detection (in ngAfterViewInit
), and it defaults to false.
I would recommend that you always try to use {static: true}
, unless you absolutely can't. The main benefit of this approach is not requiring the use of additional lifecycle hooks (like ngAfterViewInit
). If your element is dynamically rendered (ex: the element in your component template is inside of an *ngIf or *ngFor), you can't use static:true
. In other words, if the element isn't dynamic, it's static.
In this particular case, all of your default column templates are static (not dynamic) ng-templates which live at the bottom of your table.component.html, so you should reference them with static:true
You can also see in your existing logs, where you have added most of the component lifecycle hooks (as well as a log in your getTemplate
component function) exactly what's happening. The getTemplate
function is being used in the component template, which will run the function before the ngAfterViewInit
hook, and because you're currently using static:false
the ViewChild references being logged are undefined until the log statement inside ngAfterViewInit
.
Side Answer RE: ExpressionChangedAfterItHasBeenChecked
Per the docs, this is an error that is only thrown in development mode, specifically caused by the extra change detection cycle that runs in development mode. So as long as you build and deploy the app with a production configuration (ex: ng build --prod
) you will not see the error.
However, just because you won't see those error logs in the console in the deployed version of the app doesn't mean you can simply ignore them during development. This particular bug you're seeing would still occur, you just would not see the ExpressionChangedAfterItHasBeenChecked
error.