I've a problem using @ViewChild with a component showed through ngIf. I found various solutions but no one usefull for me. This is my main component, consisting of various step (I showed only 2 in code for brevity) with a button for forward navigation and a button to reset the component returning on first step. First step is showed on page opening:
... <div class="my-container"> <first-child *ngIf="showFirtChild"></first-child> <second-child *ngIf="showSecondChild"></second-child> </div> <button (click)="goToNextStep()"></button> <button (click)="reset()"></button> ...
export class MainComponent implements OnInit { @ViewChild(FirstChild) private firstChildComp: MyFirstChildComponent; showFirtChild: boolean = true; ngOnInit() { //here firstChildComp is defined } //code for navigate through steps reset() { this.showFirtChild= true; this.firstChildComp.fillTable(); //fillTable is a function defined in MyFirstChildComponent } ... }
During steps navigation the reference to firstChildComp is lost and when reset() is called, childComp results undefined. I know the cause is ngIf, so I tryed to use ngAfterViewInit:
ngAfterViewInit() { this.fcomp = this.firstChildComp; } reset() { this.showFirtChild= true; this.fcomp .fillTable(); }
but it doesn't resolve my problem. Any suggestion?
The problem can be caused by the *ngIf or other directive. The solution is to use the @ViewChildren instead of @ViewChild and subscribe the changes subscription that is executed when the component is ready. For example, if in the parent component ParentComponent you want to access the child component MyComponent .
ViewChildlinkProperty decorator that configures a view query. The change detector looks for the first element or the directive matching the selector in the view DOM. If the view DOM changes, and a new child matches the selector, the property is updated.
Conclusion. The @ViewChild decorator allows us to inject into a component class references to elements used inside its template, that's what we should use it for. Using @ViewChild we can easily inject components, directives or plain DOM elements.
The ViewChild decorator returns the first element that matches a given directive, component, or template reference selector.
As Angular's Doc says:
"True to resolve query results before change detection runs. If any query results are inside a nested view (such as *ngIf), the query is resolved after change detection runs."
So, passing the param { static: false }
to @ViewChild resolve the problem, as it is accessed on ngAfterViewInit, instead on { static: true }
is accessed before change detection runs so on ngOnInit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With