'Looping through Angular QueryList
So I want to get all the images in my component in an array, so I am using Angular's @ViewChildren
which returns a QueryList
of ElementRef
:
@ViewChildren('img', { read: ElementRef }) images: QueryList<ElementRef>;
However, when ever I try to loop through the list am can't ever seem to get hold of the nativeElement
. I am calling this in ngAfterViewInit()
this.images.forEach((img, index) => console.log("Image", img.nativeElement));
I don't get anything in the console.log
, no error nothing.
This in turn does work:
console.log("this.images", this.images);
Below is an image of the log of console.log("this.images", this.images)
:
Here the html
:
<div class="swiper-slide" *ngFor="let exhibit of exhibits; let i = index">
<app-exhibit-images exhibitImagesId="{{ exhibit.fields.eventImages[0].sys.id }}" [eventPicturesStart]="eventPicturesStart" (sendEndEventPictures)="getEndEventImages($event)"></app-exhibit-images>
<div id="exhibit-{{i}}"class="gallery__content" [ngClass]="{'show-event-pictures' : eventPicturesStart}">
<div class="gallery__poster" [ngClass]="{'gallery-expand' : isGalleryExpanded }">
<figure class="poster__image">
<picture>
<source srcset="{{ exhibit.fields.photo.fields.file.url }}" type="img/png">
<img #img src="{{ exhibit.fields.photo.fields.file.url }}" alt="{{ exhibit.fields.photo.fields.description }}">
</picture>
</figure>
</div>
<div class="gallery__text" [ngClass]="{'gallery-expand' : isGalleryExpanded }">
<button class="gallery-expand-button" (click)="expandGallery()"></button>
<h2 class="gallery__heading">{{ exhibit.fields.title }}</h2>
<h3 class="gallery__subheading">{{ exhibit.fields.subTitle }}</h3>
<h4 class="gallery__artist">{{ exhibit.fields.artist }}</h4>
<p class="gallery__description" *ngIf="exhibit.fields.description">{{ exhibit.fields.description }}</p>
</div>
</div>
</div>
What am I missing?
Solution 1:[1]
I ran into a similar issue with @ContentChildren
. The solution was to subscribe to the changes
observable of the QueryList
.
Essentially, this will trigger whenever any of the state of the children changes. Normally this wouldn't be necessary but if your list of children is loaded in via a GET, this ensures the QueryList
is data is loaded before executing on it. Its important to note the subscription will fire again whenever the any of the children's content changes.
@ContentChildren(forwardRef(() => ChildComponent), { descendants: true })
private children: QueryList<ChildComponent>;
ngAfterContentInit() {
// subscribe to changes
this.children.changes.subscribe(children => {
children.forEach(child => {
// do something with each child...
});
});
}
Solution 2:[2]
Don't call your loop in ngAfterViewInit
, use ngAfterViewChecked
instead. This will be triggered AFTER your child components are checked.
See lifecycle-hooks
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | jrswgtr |
Solution 2 | A. Sa. |