Angular 6 nested ViewChild inside ng-template is null Angular 6 nested ViewChild inside ng-template is null angular angular

Angular 6 nested ViewChild inside ng-template is null


You can call the method audio.someFunction() from the template itself.

<ng-template #modal let-modal>  <div style="background-color: red;">   <h1>Modal header</h1>  <app-audio #audio></app-audio>  <!-- on click, call audio comp method someFunction() using its reference -->   <button (click)="audio.someFunction()">Operate with audio from inside modal</button>  </div></ng-template>

No need of @ViewChild property here. This should do the trick for you.

Forked demo


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


For me all this solutions did not work and I still wanted to access my own component inside a third party ng-template. Here is my 'solution'. I don't think this is best practice but a desperate solution to get what I want ;-) It only works for your own components of course.

// mycomponent.ts => component that needs to be accessed import { Component, Output, EventEmitter, AfterViewInit } from '@angular/core';@Component({    selector: 'my-component',    templateUrl: './mycomponent.html'})export class MyComponent implements AfterViewInit {   @Output() initialized: EventEmitter<MyComponent> = new EventEmitter<MyComponent>();   ngAfterViewInit(): void {        this.initialized.emit(this);   }   reload(): void {        // Do something   }}// somecomponent.html => component with <ng-template> holding MyComponent<ng-template>    <div class="btn-group ml-2">      <my-component (initialized)="onMyComponentInitialized($event)"></my-component>    </div></ng-template>// somecomponent.ts => component with <ng-template> holding MyComponentimport { Component, OnDestroy } from '@angular/core';import { MyComponent } from '../../my-component';@Component({    selector: 'some-component',    templateUrl: './some-component.html'})export class SomeComponent implements OnDestroy {    private _myComponent: MyComponent = null;    onMyComponentInitialized(component: MyComponent) {        this._myComponent = component;    }    someOtherMethod() {        if (this._myComponent) {            // Call some method on the component            this._myComponent.reload();        }    }    ngOnDestroy() {        this._myComponent = null;    }}