Reputation: 121
Suppose in my angular code i have access to a html element by viewChild('someDiv')
or constructor(private elem: ElementRef){}
.Whenever my angular component gets loaded i want access to that elements some property so i can store it in variable.Ex- i want to get the elements width as soon as that component gets loaded so my code is
@ViewChild('someDiv') someDiv: ElementRef;
someDivWidth;
ngOnInit(){
someDivWidth = this.someDiv.nativeElement.clientWidth;
}
and my html code
<div #someDiv>some text</div>
But this is giving error like nativeElement is undefined.So how can i solve this?My basic need is as soon as this component loads i want to set that div's width in variable without triggering any function.
Update:
So using constructor(private elem: ElementRef){}
isn't giving any error and i can get access to width by
ngOnInit(){
this.someDivWidth = this.elem.nativeElement.querySelector('.someCssSelector');
}
But suppose i have some products data which i am fetching from backend and storing in an array in ngOnInit lifecycle hook and in my template creating multiple div's depending upon the products data array using lifecycle hook.In that case if i want to get all the product div's currently i am doing like
products = [];
items;
ngOnInit(){
this.productService.getProducts().subscribe(products => {
this.products = products
})
this.itmes = this.elem.nativeElement.querySelectorAll('.each-product');
console.log(this.items)
}
this is giving me a empty nodeList.I thought at the time of setting this.items my products don't gets loaded from backend thats why its giving me empty array or nodeList but putting that last two lines in subscribe() like
ngOnInit(){
this.productService.getProducts().subscribe(products => {
this.products = products
this.itmes = this.elem.nativeElement.querySelectorAll('.each-product');
console.log(this.items)
})
}
and my html code is
<div>
<div *ngFor='let product of products' class='each-product'>...</div>
</div>
is still giving me an empty array or nodelist.What to do??
Upvotes: 2
Views: 3061
Reputation: 401
Angular uses its algorithms to detect changes in data and respond to the view. If you want to opreate the DOM after the request was completed, you may not be able to get it because the view hasn't been updated yet, and you can understand that Angular also needs time to update the view. Offer two solutions
ChangeDetectorRef
to perform change detection manuallysetTimeout
Upvotes: 0
Reputation: 617
ngOnInit
lifeCycle is invoked once when component instantiated and called right after the properties checked for the first time, and before its children checked.
If You want to be sure that view has been loaded (@ViewChild
depends on view to be rendered) you should use ngAfterViewInit
which is called after component view and it's children view are created and ready.
UPDATE: If you need to access viewChild
in ngOnInit
you have to set { static: true }
Upvotes: 1
Reputation: 129
You should do it in the ngAfterViewInit method of the angular life cycle.
ngAfterViewInit(){
this.someDivWidth = this.elem.nativeElement.querySelector('.someCssSelector');
}
Upvotes: 3