javascriptangulardomionic4

clientHeight & clientWidth always zero in Angular & Ionic Component


I have barcode component, when used it should show a barcodescanner in the correct width and height (the containers width and height). These values are needed to correctly initialize the scanner.

I want to get the clientHeight and clientWidth using a ElementReference in angular. Like so:

@ViewChild('scannercontainer') scannerContainer: ElementRef;

ngAfterViewInit() {
    console.log('Container clientHeight: ', this.scannerContainer.nativeElement.clientHeight);
    console.log('Container clientWidth: ', this.scannerContainer.nativeElement.clientWidth);
}

Html:

<div class="viewport-wrapper" #scannercontainer>
    <div [hidden]="!scannerInitialized" class="viewport" #scanner></div>
</div>

SCSS:

$card-padding: 20px;
$card-border-radius: 6px;
$card-background-color: #ffffff;

:host {
    display: block;
    width: 100%;
    height: 250px;
}


::ng-deep .viewport-wrapper {
    display:block;
    width: 100%;
    height: 250px; // height: 100%;
    border-bottom-left-radius: $card-border-radius;
    border-bottom-right-radius: $card-border-radius;
    overflow: hidden;
    position: relative;
    .viewport {
        display:block;
        canvas {
            position:absolute;
            top: 0;
            left: 0;
        }
    }
}

When I check the console log the clientHeight & clientWidth is always zero, so I tried adding a timeout using the setTimeout(); method. This worked, but only if I waited 3 seconds. A zero would not work.

Are there any other solutions I could use?

I tried putting the barcode-component source directly into the page I was planning to use it in. This worked correctly, but I'm really curious why this won't work.


Solution

  • In order to get height from template to component you can use @ViewChild()... Complete working example is in this StackBlitz Link

    // your HTML file is..
    
    <div style="width:50vw; margin: 0 auto; border: 1px solid red; padding:1rem; text-align:center" #barcode>
    
         <app-barcode [ObjectHeight]="barcodeHeight" >
         </app-barcode>
    </div>
    

    // Your Component.ts is ...

    @ViewChild ('barcode', {static:true}) barcode : ElementRef;
    
       constructor(private cdr: ChangeDetectorRef){}
    
    ngAfterViewInit(){
       this.barcodeHeight= this.barcode.nativeElement.clientHeight;
       this.cdr.detectChanges();
    }
    

    // Your Barcode Component.ts is...

     height;
      @Input ('ObjectHeight') set heightFromApp(value){
        this.height= value;
      }