3

I have a demo Here

I have a div in a component that is shown with an *ngIf

I need to know the height of this element.

I can't seem to do this before it is displayed or in the function that shows the element.

Is there an event that occurs that I can use to get the height

import { Component, Input, ElementRef, OnInit, ViewChild, AfterViewInit } from '@angular/core';

@Component({
  selector: 'child-comp',
  templateUrl: './child.component.html'
})

export class ChildComponent implements OnInit, AfterViewInit {

  @Input() parent: ElementRef;

  private block: ElementRef;

  @ViewChild('block') set content(content: ElementRef) {
    this.block = content;
 }

  show: boolean = false
  blockHeight: number

  constructor(){ }

  // ngOnInit(){
  //   this.blockHeight = this.block.nativeElement.clientHeight;
  // }

  ngAfterViewInit(){
    this.blockHeight = this.block.nativeElement.clientHeight;
    console.log('AfterViewInit '+this.blockHeight);
  }

  showBlock(){
    this.show = !this.show
    this.blockHeight = this.block.nativeElement.clientHeight;
    console.log('showBlock '+this.blockHeight);
  }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
ttmt
  • 5,822
  • 27
  • 106
  • 158
  • You cannot get the height before it is displayed with ngIf (it simply isn't there). – Carsten May 04 '18 at 06:17
  • So is there any way to know when it is there and then capture the height as soon as it is avaible – ttmt May 04 '18 at 07:20
  • Possible duplicate of [Event to fire when an angular \*ngIf statement evaluates in template](https://stackoverflow.com/questions/44472771/event-to-fire-when-an-angular-ngif-statement-evaluates-in-template) – luiscla27 May 08 '19 at 00:36

3 Answers3

1

What you have to do is wait for Angular to run its change detection when you show your html-element. Putting a setTimeout() inside your showBlock()-method, you wait a tick, and then the block element is defined (it is present in DOM). You cannot get the height of the element before it is shown, because it is not present in DOM.

In your showBlock method:

showBlock(){
    this.show = !this.show
    setTimeout(()=>{ // wait a tick in order to get the element of block
     this.blockHeight = this.block.nativeElement.clientHeight;
     console.log('showBlock '+this.blockHeight);
    });
  }

See updated Stackblitz

John
  • 10,165
  • 5
  • 55
  • 71
0

You can use hidden instead of ngIf:-

<div>
  <button (click)="showBlock()">Show Block</button>
</div>
<div class="child-component" [hidden]="show" #block>
  <a href="">Link</a>
  <a href="">Link</a>
  <a href="">Link</a>
  <a href="">Link</a>
</div>

And make use to remove display: block from .child-component class.

Sagar Kharche
  • 2,577
  • 2
  • 24
  • 34
0

I also faced a similar situation in which my Angular component was being rendered after ngIf condition and I wanted to use the height of the element to get some class. As John said above "What you have to do is wait for Angular to run its change detection when you show your html-element". But in his answer there is a problem sometimes, we might not know the time change detection takes to run, so after a tick was not working in my case. As there is no way to capture the *ngIf event, so what I did as a hack is call the function again inside the function which needs the height of element if the element's height is 0.See below

showBlock(){
  let self = this;
  this.show = !this.show
  if(this.show && this.block.nativeElement.clientHeight == 0){
    setTimeout(() => { 
               self.showBlock();
     },500); // After a tick execute again
    return;
   }//End If

this.blockHeight = this.block.nativeElement.clientHeight;
console.log('showBlock '+this.blockHeight);
}
Gaurav Pandvia
  • 805
  • 7
  • 13