Search code examples
javascripthtmlangularhookgetelementbyid

How can I select a html element which loaded dynamically in Angular?


I want to select a specific html element that created dynamically. But "list" variable which create the html blocks is filling with http request and dom not loaded immediately. I want to select the element via id that got from url and equal to list item's id. So selected element is undefined even if I select the element in ngAfterViewInit hook. How can I select?

HTML

<div id="wrapper">
    <ng-container *ngFor="let item of list">
        <div [id]="item.id">{{item.content}}</div>
    </ng-container>
</div>

TS

list = null;
selectedItemId = null;

ngOnInit() {
    this.selectedItemId = this.activatedRoute.snapshot.params.id;
}

getList() {
    this.http.get('http://api.example.com').subscribe(
        result => this.list = result
    )
}

ngAfterViewInit() {
    const htmlElement= document.getElementById(this.selectedItemId);

    /* Some codes that using htmlElement variable */
}

Solution

  • If you refer to the HTML elements with @ViewChildren, you can subscribe to the QueryList.changes event to be notified when the elements appear in the DOM.

    In the template, set a template reference variable on the item elements:

    <div id="wrapper">
      <ng-container *ngFor="let item of list">
        <div #itemElement [id]="item.id">{{item.content}}</div>
      </ng-container>
    </div>
    

    In the code, use that variable name to refer to the elements with ViewChildren:

    @ViewChildren("itemElement") private itemElements: QueryList<ElementRef>;
    
    ngAfterViewInit() {
      this.itemElements.changes.subscribe(() => {
        console.log("Item elements are now in the DOM!", this.itemElements.length);
        const htmlElement = document.getElementById(this.selectedItemId);
        ...
      });
    }
    

    See this stackblitz for a demo. Please note that the ng-container is not necessary if it contains only one div element. You can apply the *ngFor directive directly to that element.