0

I am trying to get pixel height of this <div class="bundles-wrap enterprise" element using getBoundingClientRect().height or this.elementView.nativeElement.offsetHeight.

This is my HTML:

<div class="row d-flex align-items-end" *ngFor="let value of valueList">
        <!--        start-->
          <div class="bundles-wrap enterprise" id="card-id" #card>
            <div class="hdr">
              <h2>{{value.Name}}</h2>
              <span>What you’ll get</span>
            </div>
</div>
</div>

This is my component class:

 valueList: Model[];
 @ViewChild('card', {read: ElementRef, static:false}) elementView: ElementRef;
    ngAfterViewInit(): void{
     this.loaderService.showLoader("shell-content-loader", "Processing…");
     this.getValueList();
    
    }
    
    getValueList(){
    this.service.getvalueDetails().subscribe(res => {
           this.valueList = res;
              if (this.valueList.length != 0) {
                this.loaderService.hideLoader("shell-content-loader");
                const height1 = document.getElementById('card-id').getBoundingClientRect().height;
                const height2 = this.elementView.nativeElement.offsetHeight;
                console.log(height1);
              }
            });
        
        }

And I am trying to get height1, height2 but it says Cannot read property 'getBoundingClientRect' of null in Angular. None works.

Alireza Ahmadi
  • 8,579
  • 5
  • 15
  • 42
Mands
  • 171
  • 1
  • 3
  • 14

2 Answers2

1

You are trying to get element with ID card-id.

You also are creating element with this ID in an *ngFor, so multiple element will have same ID.

In your code, you set values which will be used in ngFor, and just after searching for element. So, Angular will not find element because they are not loaded yet.

I suggest you to identify all element differently. You can do it with specific CSS class, or like that:

<div class="row d-flex align-items-end" *ngFor="let value of valueList">
    <div class="bundles-wrap enterprise" id="card-id-{{ value.ID }}" #card>
        <div class="hdr">
            <h2>{{value.Name}}</h2>
            <span>What you’ll get</span>
        </div>
    </div>
</div>

And in the angular side:

valueList: Model[];

@ViewChild('card', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(): void{
    this.loaderService.showLoader("shell-content-loader", "Processing…");
    this.getValueList();
}
    
getValueList(){
    this.service.getvalueDetails().subscribe(res => {
        this.valueList = res;
        this.loaderService.hideLoader("shell-content-loader");
        for(let vl of res) {
            const height1 = document.getElementById('card-id-' + vl.ID).getBoundingClientRect().height;
            const height2 = this.elementView.nativeElement.offsetHeight;
            console.log(height1);
        }
   });
}
Elikill58
  • 4,050
  • 24
  • 23
  • 45
1

You can append index of each step to your id:

<div class="row d-flex align-items-end" *ngFor="let value of valueList; let i = index">
          <div class="bundles-wrap enterprise" [attr.id]="'card-id' + i" #card>
            <div class="hdr">
              <h2>{{value.Name}}</h2>
              <span>What you’ll get</span>
            </div>
          </div>
</div>

And in your component:

this.service.getvalueDetails().subscribe(res => {
            this.valueList = res;
            if (this.valueList.length != 0) {
                this.loaderService.hideLoader("shell-content-loader");

                for (var i = 0; i < res.length; i++)  {
                    const height1 = document.getElementById('card-id' + i).getBoundingClientRect().height;
                    const height2 = this.elementView.nativeElement.offsetHeight;
                    console.log(height1);
                }
            }
        });
Alireza Ahmadi
  • 8,579
  • 5
  • 15
  • 42