Search code examples
angularcore-js

Angular: Expression has changed after it was checked. Previous value: 'undefined'. Current value: '[object Object]'


I have an issue after upgrading angular and dependencies to more recent versions.

The application works as before but I saw an error message in console that I did not have before:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: '[object Object]'.

It seems that I have this issue with a more recent version of 'core-js'.

After searching on the Internet, it seems that the error can occurs with @ViewChild used for the autocomplete but I do not understand what is wrong. Also, it seems that the code responsible of this error is the following one:

  • In html of a first component, I use a component with autocomplete:

<mat-form-field>
  <mat-placeholder>...</mat-placeholder>
  <input class="t-myClass" type="text" matInput
    [formControl]="myFormGroup.controls['myField']" (change)="resetValidity()"
    [matAutocomplete]="myAutocomplete.autocomplete" #myField>
  <app-my-autocomplete #myAutocomplete="appMyAutocomplete"
    [inputFormControl]="myFormGroup.controls['myField']" [inputElement]="myField">
  </app-my-autocomplete>
</mat-form-field>

  • In the component with autocomplete component I have this:

export class MyAutocompleteComponent implements OnInit, OnChanges, OnDestroy {

  @Input()
  inputFormControl: FormControl;

  @Input()
  inputElement: HTMLInputElement;

  @ViewChild('autocomplete')
  autocomplete: MatAutocomplete;

  filteredObjects: Observable<MyElement[]>;

  //inputFormSubscription: Subscription;

  constructor(
    private myElementService: MyElementService,
    ...
  ) { }

  ngOnChanges() {
    
  }

  onSelection() {
    if (this.inputElement) {
      // Need to create a timeout cause the input is selected just after the option selection
      setTimeout(() => {
        this.inputElement.blur();
      }, 0);
    }
  }

  ngOnInit() {
    //this.inputFormSubscription = this.inputFormControl.valueChanges.subscribe(val => this.filteredObjects = this.geographyElementService.getGeographyElements(val));
    this.filteredObjects = this.inputFormControl.valueChanges.pipe(switchMap(val => this.geographyElementService.getGeographyElements(val)));
  }

  ngOnDestroy() {
    //this.inputFormSubscription.unsubscribe();
  }

  ...
}

  • The html associated to this component (with autocomplete) is:

<mat-autocomplete #autocomplete [displayWith]="label.bind(this)" panelWidth="240px">
    <mat-option *ngFor="let object of filteredObjects | async " [value]="object" (onSelectionChange)="onSelection()">
        {{ object.code }} - {{ object.description }}
    </mat-option>
</mat-autocomplete>

When debugging, I found that the current value corresponding to the error is a MatAutocomplete object so it seems to confirm that it is this code but I do not understand why because the code is working.

Can yu help me to solve the issue please?

Edit: I updated the code according to answer given but the error still occurs.


Solution

  • The solution was to use static with value true for autocomplete:

    @ViewChild('autocomplete', { static: true })
    autocomplete: MatAutocomplete;