Search code examples
javascriptangularng-bootstrapviewchild

Angular 6 nested ViewChild inside ng-template is null


We are using a modal (ng-bootstrap's one) in our application. That modal looks like:

<ng-template #modal let-modal>
    <app-audio #audio></app-audio>
</ng-template>

And it's logic:

@ViewChild('modal')
modal: ElementRef;

@ViewChild('audio')
audio: AudioComponent;

The modal is opened with:

this.modalService.open(this.modal, { size: 'lg' });

Everything fine till here. The modal opens and the audio component is shown. But now, we want to access the logic that is inside the component, and when doing something like:

this.audio.somePublicComponentFunction()

It happens that this.audio is null. I have already tried to get the child with angular's change detector, but cannot find a way to properly link this.audio with the actual component. Any ideas? Thanks a lot.

You can see the issue here: stackblitz.com/edit/angular-ofmpju


Solution

  • You can read the child component without the refrence variable like this

    @ViewChild(AudioComponent)
    audio: AudioComponent;
    

    This will give you the instance of the child component - where you can access the method

    this.audio.someComponentFunction()

    Your html

    <ng-template #modal let-modal>
        <app-audio></app-audio>
    </ng-template>
    

    This will solve your issue i think - Happy coding

    Update:

    Hope i found a workaround for this issue - if in case you want to trigger only one function you can use this method

    I have just added a property with getter and setter and triggered the function when we set the value

    @Input()
      get triggerFunction(): boolean {
        return this.runFuntion;
      }
    
      set triggerFunction(value: boolean) {
        this.runFuntion = value;
        this.someFunction();
      }  
    

    So this causes to trigger the function every time when the model show up - property mentioned above belongs to the child component which is nested inside the <ng-template> so finally the model template will read as mentioned below:

    <ng-template #modal let-modal>
      <app-audio [triggerFunction]="true"></app-audio>
    </ng-template>
    

    Hope this will act a workaround for now - Thanks