2

Within my template, I use *ngFor

<div #listofbars *ngFor="let points of pointsNormalized; let i =index" [attr.data-index]="i">

<div *ngIf="i < 10" class="ranking d-flex align-items-center" [ngClass]="setBarClass(i)" [attr.id]="'bar-id-' + i">
   

And then I try to access the 0th child element like so:

@ViewChildren("listofbars")  list_container: QueryList<ElementRef>;

if (this.list_container) {
 if (this.list_container.toArray()[0]) {
  console.log(this.list_container.toArray()[0].nativeElement);
 }
}

   

However, it appears, when I check the Chrome console, that the element is actually not contained within the html source. I'm trying to use the element reference to build an animation, but it does not work when I access elements within ngFor (it has worked when I tried it on elements outside of ngFor). What's the correct to get a native element reference within the ngFor directive?

Krishna Rathore
  • 9,389
  • 5
  • 24
  • 48
Dan
  • 475
  • 2
  • 5
  • 11
  • 2
    Where in the application is this code? You can't access the ViewChildren elements until after the `ngAfterViewInit` lifecycle hook. – DeborahK Aug 16 '18 at 00:29

1 Answers1

1

Although I can't know for sure where you're running the logging code, I'm sure it's because ViewChildren is not set until ngAfterContentInit. So, the first thing that needs to be done is put your code in ngAfterViewInit() { } (triggered after contentInit).
Next, I would be subscribing to changes on the QueryList. So:

@ViewChildren("listofbars")  childrenQuery: QueryList<ElementRef>;

ngAfterViewInit() {
    this.childrenQuery
      .changes
      .subscribe((list) => {
        console.log("Native element", list.toArray()[0].nativeElement);
      })
}

Or if you really need just the first entry, for aesthetics you could use

console.log("Native element", list.first.nativeElement);
Brad Axe
  • 815
  • 7
  • 17
  • Thank you. You're correct, when I was using ngOnInit, the incorrect reference to the element was being used. – Dan Aug 17 '18 at 08:12