title: How do I reference an Angular component from typescript when it may be removed by ngIf?
body: <p>I have a template which uses <code>MatInput</code> from Angular Material. I am trying to access this component from code using <code>@ViewChild</code> so I can programmatically alter the <code>focused</code> state, but this <code>MatInput</code> is not there when the view initializes - its presence is determined by an <code>*ngIf</code> directive. Basically, when the view loads, there is a <code>p</code> element with some text. If a user clicks that element, it will be replaced with an <code>input</code> where the starting value is the text of the original element. When it loses focus, it is saved and reverts back to a <code>p</code> element. The problem is that when they first click on the text to change it, the <code>input</code> that's created does not have focus - they have to click it again to start editing. I want them to be able to click once and start typing. </p>
  
  <p>Here's my relevant code.</p>
  
  <p>Template:</p>
  
  <pre><code>&lt;mat-form-field *ngIf="selected; else staticText" class="full-width"&gt;
    &lt;input matInput type="text" [(ngModel)]="text" (blur)="save()"&gt;
  &lt;/mat-form-field&gt;
  &lt;ng-template #staticText&gt;
    &lt;p class="selectable" (click)="select()"&gt;{{ text }}&lt;/p&gt;
  &lt;/ng-template&gt;
  </code></pre>
  
  <p>Typescript:</p>
  
  <pre><code>import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
  import { MatInput } from '@angular/material';
  import { AfterViewInit } from '@angular/core/src/metadata/lifecycle_hooks';
  
  @Component({
    selector: 'app-click-to-input',
    templateUrl: './click-to-input.component.html',
    styleUrls: ['./click-to-input.component.scss']
  })
  export class ClickToInputComponent implements AfterViewInit {
    @Input() text: string;
    @Output() saved = new EventEmitter&lt;string&gt;();
    @ViewChild(MatInput) input: MatInput;
  
    selected = false;
  
    ngAfterViewInit(): void {
      console.log(this.input); // shows undefined - no elements match the ViewChild selector at this point
    }
  
    save(): void {
      this.saved.emit(this.text);
      this.selected = false;
    }
  
    select(): void {
      this.selected = true;  // ngIf should now add the input to the template
      this.input.focus();    // but input is still undefined
    }
  }
  </code></pre>
  
  <p>From the docs: </p>
  
  <blockquote>
    <p>You can use ViewChild to get the first element or the directive
    matching the selector from the view DOM. <strong>If the view DOM changes, and
    a new child matches the selector, the property will be updated.</strong></p>
  </blockquote>
  
  <p>Is <code>*ngIf</code> working too slow, and I'm trying to access <code>this.input</code> too soon before the property is updated? If so, how can I wait until <code>*ngIf</code> is done replacing the DOM and then access the <code>MatInput</code>? Or is there some other way to solve my focusing problem altogether that I'm just not seeing?</p>