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; }}