title: Angular: measuring buttons and setting property after they are drawn
body: <p>I have a scenario where I am displaying a series of buttons. If the screen is not large enough for the buttons, I display a combobox.</p>
  
  <p>The template code of interest:</p>
  
  <pre><code>&lt;div *ngIf="useDropdown" ngbDropdown&gt;drop down code...&lt;/div&gt;
  &lt;button *ngFor='let btn of buttons'&gt;{{btn.title}}&lt;/button&gt;
  </code></pre>
  
  <p>The component code of interest:</p>
  
  <pre><code>public useDropdown:boolean;
  
  ngAfterViewInit() {       
    this.useDropdown = this.isDropdownNeeded();//returns a boolean 
  }
  </code></pre>
  
  <p>So the idea is that once the buttons are drawn on the screen, I measure (in the isDropdownNeeded method) if there is enough space for the buttons. Then return a boolean which is bound to an ngIf to show or hide a combobox. The isDropdownNeeded() also removes the buttons if that is the case.</p>
  
  <p>Problem is that I am getting <code>ExpressionChangedAfterItHasBeenCheckedError</code>. This is caused by the code updating useDropdown's value before the current cycle finishes. </p>
  
  <p>I tried using setTimeOut, which makes the buttons display for a brief moment and flicker off before showing the combobox. Not visually elegant...</p>
  
  <p>I then tried:</p>
  
  <pre><code>ngAfterContentChecked() {
      this.useDropdown = this.isDropdownNeeded();
  }
  </code></pre>
  
  <p>This works but it is called all the time. I can put a mechanism to at least stop isDropdownNeeded() to get called all the time, but parts of the application get data updates often and this can get expensive...</p>
  
  <p>I found a few ways to fake ngFor event once it is done drawing, but none of them really worked.</p>
  
  <p>So, how can I measure a bunch of buttons width after they are drawn in order to set a template property without getting <code>ExpressionChangedAfterItHasBeenCheckedError</code>?</p>