0

I am trying to grab all the input elements that only exist after a boolean becomes true. So the div is wrapped around an *ngIf. I tried grabbing the elements using plain JavaScript, but it keeps returning empty. Here is my code:

test.component.html

<mat-checkbox (change)="toggleTest($event)">
    Test check box
</mat-checkbox>

<div class="form-area" *ngIf="isTestChecked">
    <input type="number">
    <input type="text">
</div>

test.component.ts

isTestChecked = false;

toggleTest(event: any) {
    this.isTestChecked = event.checked;

    if (this.isTestChecked === true) {
        const children = document.querySelectorAll('.form-area input');
        console.log(children);
    }
}

So the console.log always prints an empty array. However, if I manually type the query selector in the browser console after setting the boolean to true, then it returns both of the input elements.

What am I doing wrong? How come it won't get the input elements after they become added to the DOM? Any help would be appreciated!

o.o
  • 3,563
  • 9
  • 42
  • 71

2 Answers2

1

Do not access the DOM this way. The Angular way is using ElementRef.

Take a look, too, at those threads that explain how to use: Angular 2 @ViewChild in *ngIf

private contentPlaceholder: ElementRef;
@ViewChild('contentPlaceholder') set content(content: ElementRef) {
   this.contentPlaceholder = content;
}

<div #contentPlaceholder *ngIf="isTestChecked">
    <input type="number">
    <input type="text">
</div>
Christian Benseler
  • 7,907
  • 8
  • 40
  • 71
0

Angular updates the DOM asynchronously, so you can't access the updated DOM elements in the same event loop. If you really need to manipulate the DOM directly, try add a timeout before the query selection.

this.isTestChecked = event.checked;

setTimeout(() => {
    if (this.isTestChecked === true) {
        const children = document.querySelectorAll('.form-area input');
        console.log(children);
    }
})
MarkoCen
  • 2,189
  • 13
  • 24
  • Thank you, this works as well. However, I didn't want to use `setTimeout`. – o.o Jun 07 '18 at 18:43
  • This is not the `Angular way` (using document.querySelectorAll). Plus, you can'ct rely on setTImeout, there is no guarantee the DOM will be rendered when the setTImeout callback is called. – Christian Benseler Jun 07 '18 at 18:46
  • Yea, that was my main reason of not wanting to use it. Depending on the connection or some other reason, it could not be fully rendered. – o.o Jun 07 '18 at 21:02