I want to access a template reference variable using @ViewChild
while the element is inside an element with async
pipe present as follows:
<ng-container *ngIf="productTemplates$ | async as templates; else loading">
<div >
<mat-checkbox #selectAll (change)="toggleAllTemplates($event)">Select All</mat-checkbox>
</div>
</ng-container>
How can I safely access the #selectAll
reference early in the lifecycle of the component (like in ngAfterViewInit
) while it is not present until the API call for products is returned?
CodePudding user response:
I would replace the @ViewChild
with @ViewChildren
instead. It might seem not that intuitive at first, but the reasoning behind it is that @ViewChildren
always returns you a QueryList
that is not null
inside the ngAfterViewInit
lifecycle method.
You can then subscribe to the changes
observable to be notified each time this query list changes
@ViewChildren('selectAll', { read: MatCheckbox }) selectAllCheckboxes!: QueryList<MatCheckbox>;
ngAfterViewInit() {
this.selectAllCheckboxes.changes.pipe(
filter(() => this.selectAllCheckboxes.length > 0)
).subscribe(() => this.doSomethingWithTheCheckbox());
}
private doSomethingWithTheCheckbox() {
const selectAllCheckbox = this.selectAllCheckboxes.first;
// here you should be able to safely use your selectAllCheckbox
}