Home > database >  Trying to get data from a child component will always return undefined
Trying to get data from a child component will always return undefined

Time:12-29

I could not find a solution yet for my little issue. As I needed to change somebodies code I ran into an issue with getting data from the child component. The issue for what I can see is that the child component is NOT rendered before that I want to access it. I cant move the forms into the template variable scope so thats not a option. After rendering the child component I wanted to do some more stuff thats why I needed the data of the child.

Notice that the child component is a third party component.

parent template

<form (ngSubmit)="FormSubmit()">
  // some inputs here
  <button>print QR</button>
</form>

[more forms ...]

// this will ONLY be renderd if I click the print button!
<div *ngIf="qrLoaded">
  <qrcode #qrBlock></qrcode>
</div>

Parent Component

@ViewChild('qrBlock') set qrBlock(qrBlock: QRCodeComponent) {
  this.test = qrBlock
}

FormSubmit(): void {
   // setting up qr code data
   this.qrLoaded = true

   console.log(this.test)// will return undefined
   setTimeout(() => console.log(this.test) ,5000);// will return the data
}

CodePudding user response:

you can use [hidden]="!qrLoaded" instead of *ngIf="qrLoaded" or @ViewChild('qrBlock',{static:true}) ...

CodePudding user response:

I created and tested a simple example that is almost equivalent to yours, but it uses a <div>-element as ViewChild instead of <qrcode>. I'm aware that this might not the final solution, but it might help us narrow down the causes of the problem. I think it proves that a html-element that is tagged as [hidden] = "true", is usually accessible as soon as the user is able to click any button:

<div #qrBlock [hidden]="isQrBlockHidden">Hello, world!</div>
<button (click)="toggleQrBlock()">Toggle</button>
isQrBlockHidden = true;

@ViewChild('qrBlock')
qrBlock!:any;

toggleQrBlock() {
    this.isQrBlockHidden = !this.isQrBlockHidden;
}

CodePudding user response:

When using ViewChild you will have to wait for the component to render.

You have to put your code in the ngAfterViewInit() method otherwise this.test will remain undefined.

something like:

@ViewChild('qrBlock') qrBlock!: QRCodeComponent;

ngAfterViewInit() {
  this.qrLoaded = true //EDIT: forgot this part
  this.test = this.qrBlock
  console.log(this.test) //component will be rendered here
}

To use ngAfterViewInit() you will have to implement it like the example below:

export class SomeComponent implements AfterViewInit {
...
}

  • Related