title: How to fix a ExpressionChangedAfterItHasBeenCheckedError
body: <p>I have an application with a mat-autocomplete element in it with cities as options. The cities come from a database. There is a button to add an input element. This is done by having a div element with a *ngFor property that loops over a property in the component.ts file. When the add-button is clicked an element is added to the property and so an input is added. But when i type in a city name in the first input and then try to add an input element i get the ExpressionChangedAfterItHasBeenCheckedError.</p>
  
  <p>I have found that a lot of people get this error but i've tried all the given solutions but non of them of them seem to work. Like :</p>
  
  <pre><code>        startWith(''),
          delay(0),
          map(value =&gt; this._filter(value))
        );
  </code></pre>
  
  <pre><code>ngAfterViewInit(){
      this.cd.detectChanges();
    }
  </code></pre>
  
  <pre><code>var request = new CityCreationRequestModel();
      request.name = "";
      Promise.resolve(null).then(() =&gt; this.reportGroupCreationRequest.cityReportGroups.push(request));
  </code></pre>
  
  <p>and trying with timeOuts.</p>
  
  <p>this is my html file :</p>
  
  <pre><code>&lt;div class="container"&gt;
      &lt;mat-card&gt;
          &lt;mat-card-header&gt;
              &lt;mat-card-title&gt;Voeg een reportgroep toe&lt;/mat-card-title&gt;
              &lt;mat-card-subtitle&gt;Geef emailadressen op die verbonden worden met de rapporten van bepaalde steden&lt;/mat-card-subtitle&gt;
          &lt;/mat-card-header&gt;
          &lt;mat-card-content&gt;
                  &lt;form (ngSubmit)="onSubmit()" #addReportGroup="ngForm" *ngIf="!isLoading"&gt;
  
                      &lt;div *ngFor="let city of reportGroupCreationRequest.cityReportGroups" class="form-row"&gt;
                        &lt;mat-form-field&gt;
                            &lt;input placeholder="Stad" required [(ngModel)]="city.name" type="text" matInput [formControl]="myControl" [matAutocomplete]="auto" name="cityInput"&gt;
                            &lt;mat-autocomplete autoActiveFirstOption #auto="matAutocomplete"&gt;
                                &lt;mat-option *ngFor="let cityName of filteredOptions | async" [value]="cityName"&gt;
                                  {{ cityName }}
                                &lt;/mat-option&gt;
                              &lt;/mat-autocomplete&gt;
                        &lt;/mat-form-field&gt;
                        &lt;/div&gt;
  
                        &lt;button mat-raised-button (click)="addCity()"&gt;Voeg een stad toe&lt;/button&gt;
  
                          &lt;div class="form-row"&gt;
                            &lt;button mat-raised-button type="submit" [disabled]="!addReportGroup.valid" class="submitButton"&gt;Opslagen&lt;/button&gt;
                          &lt;/div&gt;
                        &lt;/form&gt;
                        &lt;mat-spinner [style.display]="isLoading ? 'block' : 'none'"&gt;&lt;/mat-spinner&gt;
          &lt;/mat-card-content&gt;
      &lt;/mat-card&gt;
  </code></pre>
  
  <p>and this is my .ts file :</p>
  
  <p>the filter if for the mat-autocomplete element</p>
  
  <pre><code>export class AddReportGroupComponent implements OnInit {
  
    myControl = new FormControl();
    filteredOptions: Observable&lt;string[]&gt;;
  
    public reportGroupCreationRequest: ReportGroupCreationRequestModel = new ReportGroupCreationRequestModel();
  
    public cities: Array&lt;CityResponseModel&gt;;
    public cityNames: Array&lt;string&gt;;
    private isLoading: boolean;
  
    constructor(private reportGroupService: ReportGroupService,
      private cd: ChangeDetectorRef) { 
    }
  
    ngOnInit() {
      this.isLoading = true;
      this.reportGroupService.getCities().subscribe(result =&gt; {
        this.cities = result;
        this.cities.sort((a,b) =&gt; a.name.localeCompare(b.name));
        this.cityNames = this.cities.map(c=&gt;c.name);
      }).add(()=&gt; {
        this.isLoading = false;
        this.filteredOptions = this.myControl.valueChanges.pipe(
          startWith(''),
          delay(0),
          map(value =&gt; this._filter(value))
        );
      });
  
      this.reportGroupCreationRequest.cityReportGroups.push(new CityCreationRequestModel());
      this.reportGroupCreationRequest.emailReportGroups.push(new EmailCreationRequestModel());
    }
  
  //doesn't seem to do anything
    ngAfterViewInit(){
      this.cd.detectChanges();
    }
  
    private _filter(value: string): string[] {
      const filterValue = value.toLowerCase();
  
      return this.cityNames.filter(cn =&gt; cn.toLowerCase().indexOf(filterValue) === 0);
    }
  
    addCity(){
      var request = new CityCreationRequestModel();
      request.name = "";
      Promise.resolve(null).then(() =&gt; this.reportGroupCreationRequest.cityReportGroups.push(request));
    }
  </code></pre>
  
  <p>and these are my models that I use :</p>
  
  <pre><code>export class ReportGroupCreationRequestModel {
      public cityReportGroups: Array&lt;CityCreationRequestModel&gt; = new Array&lt;CityCreationRequestModel&gt;();
      public emailReportGroups: Array&lt;EmailCreationRequestModel&gt; = new Array&lt;EmailCreationRequestModel&gt;();
  
  }
  </code></pre>
  
  <pre><code>export class CityCreationRequestModel {
      public name: string;
  }
  </code></pre>
  
  <p>Thanks in advance</p>
  
  <p><strong>I found a solution for the problem I had :</strong></p>
  
  <p>I used both [(ngModel)] and [FormsControl] and apparantly the [(ngModel)] was part of the problem so I only used [FormsControl] and the error is gone.</p>
  
  <pre><code>addCity(){
      this.reportGroupCreationRequest.cityReportGroups[this.reportGroupCreationRequest.cityReportGroups.length - 1].name = this.myControl.value;
      Promise.resolve(null).then(() =&gt; this.reportGroupCreationRequest.cityReportGroups.push(new CityCreationRequestModel()));
    }
  </code></pre>
  
  <pre><code>&lt;div *ngFor="let city of reportGroupCreationRequest.cityReportGroups" class="form-row"&gt;
                        &lt;mat-form-field&gt;
                            &lt;input placeholder="Stad" required type="text" matInput [formControl]="myControl" [matAutocomplete]="auto" name="cityInput"&gt;
                            &lt;mat-autocomplete autoActiveFirstOption #auto="matAutocomplete"&gt;
                                &lt;mat-option *ngFor="let cityName of filteredOptions | async" [value]="cityName"&gt;
                                  {{ cityName }}
                                &lt;/mat-option&gt;
                              &lt;/mat-autocomplete&gt;
                        &lt;/mat-form-field&gt;
                        &lt;/div&gt;
  </code></pre>