1

I have a separate assetAnnotationComponent(child) which manages the annotating functionality.This component is called from my main component to perform annotation on images by mouse events.Iam getting the following error when accessing the assetAnnotationComponent object

ERROR TypeError: Cannot read property 'mychildFunction' of undefined

I tried like following in my parent component @ViewChild(AssetAnnotationComponent) assetAnnotationComponent

Here is parent component HTML

<div class="modal-body">
  <app-asset-annotation></app-asset-annotation>
  </div>

Here is parent component typescript

import { AssetAnnotationComponent } from './asset-annotation.component';

export class ParentComponent{
@ViewChild(AssetAnnotationComponent) assetAnnotationComponent;

ngAfterViewInit(){
this.assetAnnotationComponent.mychildFunction();
}
}

my child component

export class AssetAnnotationComponent{

mychildFunction()
{
console.log("success");
}

}

I am expecting "success" to printed in console so that i can be accessing the child component's function.Thanks in advance

Edit: As suggested in comments and from the question that is suggested as duplicate, i have already tried that. I am using ngViewAfterInit for calling my function so view is loaded completely. Edit 2: My child component is from different module

Edit 2: My child component is from different module

here is my sample working code

In my code if the selector of the child component is added in parent component html then i get desired output but i need to access the child component function without adding selector of child component in parent component

Shyam Sundar
  • 49
  • 1
  • 9
  • 1
    Is that **all** of the `ParentComponent` HTML? Or does the parent HTML have any `*ngIf` or similar conditional rendering logic? – Alexander Staroselsky Feb 05 '19 at 15:38
  • 3
    You seem to have the `AssetAnnotationComponent` in a Modal that you probably are showing in your `ParentComponent` conditionally. Hence you're not getting the reference to it in your ParentComponent via ViewChild. And hence the error. – SiddAjmera Feb 05 '19 at 15:40
  • 1
    Possible duplicate of [Angular 2 @ViewChild annotation returns undefined](https://stackoverflow.com/questions/34947154/angular-2-viewchild-annotation-returns-undefined) – ConnorsFan Feb 05 '19 at 15:40
  • You will find two possible solutions in [the duplicate question](https://stackoverflow.com/q/34947154/1009922): (1) using `ViewChildren` with `QueryList.changes`, (2) using a setter for `ViewChild`. – ConnorsFan Feb 05 '19 at 15:42
  • There is no conditional structure around this div. I have one button, on which i need to call the function of child element, which is not being called and i am getting undefined. – Shyam Sundar Feb 05 '19 at 15:48
  • @ConnorsFan i have checked that question and as you can see in my question i am calling my function in ngAfterViewInit only. – Shyam Sundar Feb 05 '19 at 15:51
  • @shyamsundar - Yes but you should check the other answers to the duplicate question, not the accepted answer. You will find two solutions (mentioned in my previous comment) that should work for you. – ConnorsFan Feb 05 '19 at 15:52
  • @SiddAjmera this looks like the case, i dont have any conditional structure but entire code is loaded on button click, so there might be no reference when button is clicked. In that case how do i solve this? – Shyam Sundar Feb 05 '19 at 15:57
  • @ConnorsFan i tried with viewchildren it was also not happening.My problem is similar to siddAjmera comment – Shyam Sundar Feb 05 '19 at 16:04
  • Is that the only ancestor in the template of your component? or does the template has more hierarchy levels for that element? – Jota.Toledo Feb 05 '19 at 16:44
  • It's the only one @jota.toledo – Shyam Sundar Feb 05 '19 at 17:18
  • @shyamsundar https://stackblitz.com/edit/angular-oefm77?file=src%2Fapp%2Fapp.component.ts no issues there. Can you reproduce your issue in stackblitz or similar? – Jota.Toledo Feb 05 '19 at 19:18
  • @Jota.Toledo i have added my sample code in stackblitz – Shyam Sundar Feb 06 '19 at 14:18
  • _i need to access the child component function without adding selector of child component_ then its not a child component – Jota.Toledo Feb 06 '19 at 14:22
  • i need to access the child component function without adding selector of child component in parent component HTML @Jota.Toledo – Shyam Sundar Feb 06 '19 at 14:26
  • 1
    Again, if its not present in the template of the component, then it is **not** a child component. Ergo, you cant use `ViewChild`. – Jota.Toledo Feb 06 '19 at 14:43

2 Answers2

2

in your parent component do this:

@ViewChildren('myChild') assetAnnotationComponent: QueryList<AssetAnnotationComponent>; 
public currentChildComponent: AssetAnnotationComponent;

    ngAfterViewInit(): void {
          this.assetAnnotationComponent.changes.subscribe(data => {
              this.currentChildComponent= data._results[0];
              this.currentChildComponent.mychildFunction();
          });
    }

Parent HTML do this:

<div class="modal-body">
  <app-asset-annotation #myChild></app-asset-annotation>  //notice the template variable
</div>
Nadhir Falta
  • 5,047
  • 2
  • 21
  • 43
0

Try giving a reference to the child:

<app-asset-annotation #child></app-asset-annotation>

and then in the .ts:

@ViewChild('child') child;

then you could call it as:

this.child.mychildFunction();
Fisnik Tahiri
  • 406
  • 2
  • 7