Chrillewoodz
Chrillewoodz

Reputation: 28328

How to correctly wait for the elements to get their correct width before accessing it in Angular 2?

I'm trying to make buttons the same width but I'm having problems actually waiting for Angular 2 to finish all the rendering and stuff before accessing the width of the buttons.

I tried using DoCheck which "works", by "works" I mean that it does pick up the correct width value, but only the second time it runs.

Since NgDoCheck runs twice for some reason, as soon as I add the button.style.width = widest + 'px'; statement, the buttons will all get a width of 115px, so the second time ngDoCheck runs, it will go over all the buttons again, but this time all the buttons will be set to 115px, so widest can never become the correct value of 159px since we set the value the first time ngDoCheck ran.

What would be the correct way to go about this issue? Using DoCheck just seems wrong since it runs twice, and I'm not really checking input values which is DoCheck's use case when reading the docs.

export class ButtonGroupComponent implements DoCheck {

  constructor(private _elementRef: ElementRef) {}

  ngDoCheck() {

    if (this.equalWidth) {

      let buttons = this._elementRef.nativeElement.getElementsByTagName('button');
      let widest = 0;

      for (var button of buttons) {

        if (button.getBoundingClientRect().width > widest) {
          widest = button.getBoundingClientRect().width;
        }
      }

      for (var button of buttons) {
        button.style.width = widest + 'px';
      }
    }
  }
}

Upvotes: 0

Views: 1109

Answers (1)

Chrillewoodz
Chrillewoodz

Reputation: 28328

Using AfterViewInit seems to do the trick, it only execute once resulting in the correct behavior and correct values. It's as simple as swapping DoCheck and ngDoCheck for AfterViewInit and ngAfterViewInit:

export class ButtonGroupComponent implements AfterViewInit {

  constructor(private _elementRef: ElementRef) {}

  ngAfterViewInit() {

    if (this.equalWidth) {

      let buttons = this._elementRef.nativeElement.getElementsByTagName('button');
      let widest = 0;

      for (var button of buttons) {

        if (button.getBoundingClientRect().width > widest) {
          widest = button.getBoundingClientRect().width;
        }
      }

      for (var button of buttons) {
        button.style.width = widest + 'px';
      }
    }
  }
}

Hope this helps someone else doing DOM manipulation.

Upvotes: 2

Related Questions