csfragstaa
csfragstaa

Reputation: 165

Angular viewchild undefined in ngAfterViewInit

I have 2 components, ComponentA & ComponentB, comp b is a child to comp a. ComponentB basically takes input from ComponentA & generates view. This input is obtained from a rest call. So I have wrapped my component b selector in an *ngIf. In this selector I also have a viewchild attached to it.

So basically, what I am assuming is that when ComponentB is completely rendered, I want to execute some code using my viewchild reference. This code is written in ngAfterViewInit() inside ComponentA. But when I try to access this.viewChildReference, it says undefined.

ComponentA.html

<div *ngIf="dataAvailable">
    <componentb #viewChildReference [data]="dataFromComponentA"></componentb>
</div>

ComponentA.ts

// skipping boiler code for brevity

class {
    dataAvailable = false;
    @ViewChild('viewChildReference') viewChildReference: ChildComponentModule;

    ngOnInit() {
        // fetch data from rest
        dataAvailable = true;
    }

    ngAfterViewInit() {
        this.viewChildReference.somemethod();
    }
}

ComponentB.html

// Use data from parent component and generate view

How can I solve this? What is wrong with my current approach? Please help as I am stuck up at this point..

UPDATE:

This question is not duplicate, as I have tried other solutions as suggested in comments in this question, like emitting events & other answers. Still I am facing issues, kindly unmark this as duplicate.

Upvotes: 3

Views: 1986

Answers (2)

ABOS
ABOS

Reputation: 3821

You can try

@ViewChild('viewChildReference') 
set viewChildReference(v) {
   // v is the viewChild, handle your logic here
   // if v is defined.... 
}

demo https://stackblitz.com/edit/angular-egh5dg, btw, this approach will always sync up with ngIf, if you use other approaches, viewChildReference might have stale reference, say, if you subscribe to api calls, but angular needs time to update viewChildReference and it could happen this view update is behind subscription.

Upvotes: 2

Christian
Christian

Reputation: 2831

You said you're fetching the data from a rest api. That's asynchronous. The call to ngAfterViewInit is synchronous, which means by the time it's called, your data is still not available, thus the component won't be rendered because of the ngIf. You need to call this.viewChildReference.somemethod(); once your http call completes. Something like this:

this.myService.someAPiCall().subscribe(data => {
    this.data = data;
    this.viewChildReference.somemethod();
})

Upvotes: 2

Related Questions