I want to fetch all divs starting with the id 'div'. To do so, i use @ViewChildren but i'm not able to access the divs because i have an empty array , why ?
My template
<div id="div-1">Div 1</div>
<div id="div-2">Div 2</div>
<input type="button" (click)="getDivs()">
Component
@ViewChildren('div') divs: QueryList<any>;
divList : any[];
getDivs(){
this.divList = this.divs.filter(x => x.id.lastIndexOf('div-', 0) === 0);
console.log(this.divList);
// this.divList return an empty array but i should have two results
}
Angular ViewChild and ViewChildren decorator allow us to access and manipulate HTML elements in DOM or the child component by parent component. Angular provides different ways of communication between components. Components can query the content of their templates to locate instances of element/directive/component, which are known as view children.
The syntax for angular ViewChildren @ViewChildren (directiveType) children: QueryList; This injects a reference to all the view children of type directive type. When you declare your instance variable, you specify a selector in parentheses, which is used to bind all children elements of the same type which we want to query and access in class.
Let’s say we have a ChildComponent. Ideally, you will use @angular/cli to generate your component: Otherwise, you may need to create child.component.css and child.component.html files and manually add it to app.module.ts:
As we know, all the data renders in a Tree-Down approach in angular, so, when a parent component is constructed it means the child is not created yet. So, to get the value of this reference we require component hook (which we have already discussed in component lifecycle hook article). Here, we use either ngAfterViewInit or ngAfterViewChecked hook.
As mentioned in this detailed answer, the valid selectors for ViewChildren
include component types, directive types, and template reference variables. You cannot retrieve DOM elements with ViewChildren
using CSS selectors like HTML element types (e.g. div
) or class names.
One way to make it work in your case is to generate the div
elements with an ngFor
loop, and associate a template reference variable #divs
to them:
<div #divs *ngFor="let item of [1,2]" [id]="'div-' + item">Div {{item}}</div>
<button (click)="getDivs()">Get divs</button>
You can then retrieve them in code with ViewChildren
, using the template reference variable:
@ViewChildren("divs") divs: QueryList<ElementRef>;
getDivs() {
this.divs.forEach((div: ElementRef) => console.log(div.nativeElement));
}
See this stackblitz for a demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With