1

There are two html elements in components view. The first one is being created on component initialization. The second one is being created when isDivShown == true.

let { Component, NgModule, Input, ViewChild } = ng.core;

@Component({
  selector: 'my-app',
  template: `
    <div #myelement1>Element_1</div>
    <div #myelement2 *ngIf="isDivShown">Element_2</div>
    <button (click)="changeObject()">Change the objects</button>
  `,
})
class HomeComponent {
        @ViewChild('myelement1') private el1: ElementRef;
        @ViewChild('myelement2') private el2: ElementRef;
    isDivShown = false;

    changeObject() {
      this.isDivShown = true;
      this.el1.nativeElement.className = 'myCSSclass_1';
      this.el2.nativeElement.className = 'myCSSclass_2';
    }

}

const { BrowserModule } = ng.platformBrowser;

@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ HomeComponent ],
  bootstrap:    [ HomeComponent ]
})
class AppModule { }

const { platformBrowserDynamic } = ng.platformBrowserDynamic;
platformBrowserDynamic().bootstrapModule(AppModule);

When I click the button and the method changeObject() is being called the el1 element changes it's class but the el2 element thwrows an error:

 Cannot read property 'nativeElement' of undefined

How do I use ViewChild for dynamic created html elements?

mr_blond
  • 1,586
  • 2
  • 20
  • 52
  • You can use new ViewChild static true from angular 8 https://stackoverflow.com/questions/56359504/how-should-i-use-the-new-static-option-for-viewchild-in-angular-8 – Richardson. M Aug 25 '19 at 16:14
  • So I wonder, doesnt angular 7 and lover have this ability to manipulate dynamic created objects? Make an answer, I'll check it if I dont find better solution. – mr_blond Aug 25 '19 at 16:31
  • The problem in the above code is without completing the angular change detection you are trying to access the element. for a quick check try to enclose el2.nativeelemet.class name in a setTimout – Surya Prakash Tumma Aug 25 '19 at 16:44
  • @SuryaPrakashTumma changeObject() has some ajax request. After I got this ajax answer I do this.isDivShown = true and this.el2.nativeElement.className = 'myCSSclass_2'. (in my current case ajax answer contains array of element which I display as *ngFor... but I simplified it for this question). – mr_blond Aug 25 '19 at 16:55
  • I think still the change detection haven't completed at your case(Ajax).. try to put the settimeout and check whether if you can able to access the element .. my solution is not standard way but still we can identify the issue. – Surya Prakash Tumma Aug 25 '19 at 17:06

2 Answers2

0

You could use [hidden] instead which would create a dom node onInit contrary to *ngIf.

<div #myelement2 [hidden]="!isDivShown">Element_2</div>
Anton Bks
  • 482
  • 3
  • 10
0

Qucik work around

setTimeout(() => {
      this.el2.nativeElement.className = 'myCSSclass_2';
 },10);
Surya Prakash Tumma
  • 2,153
  • 4
  • 27
  • 47