Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material mat-selection-list throws ExpressionChangedAfterItHasBeenCheckedError on reload

I have a question about mat-selection-list and reactive forms. The problem is that I create mat-selection list and then after I read from the local storage I update my form. Everything works but I get ExpressionChangedAfterItHasBeenCheckedError because it has obviously been created with default values. Is this expected behavior and how can I fix it if it is :)

you can see stack blitz example here:
https://stackblitz.com/edit/angular-ul58q4

like image 451
Dživo Jelić Avatar asked Mar 25 '26 05:03

Dživo Jelić


2 Answers

this error is because you set the form initial value but view can't detect it, so by using changeDetectorRef after set the initial value it will be right:

import { Component, AfterViewInit, Injectable ,ChangeDetectorRef } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { LocalStorageService } from './local-storage.service';

const FILTER_FORM_STORAGE_KEY = 'filterFormStorageKey';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  formGroup: FormGroup;
  typesControl: FormControl;

  types: any[] = [
    { id: 1, name: 'Type A' },
    { id: 2, name: 'Type B' }
  ];

  constructor(private _storage: LocalStorageService,
  private changeDetectorRef: ChangeDetectorRef) {
    this.formGroup = new FormGroup({
      typesControl: this.typesControl = new FormControl(null, [Validators.required])
    });
  }

  ngAfterViewInit(): void {
    const formStorage = this._storage.get(FILTER_FORM_STORAGE_KEY);
    if (formStorage) {
      this.formGroup.patchValue(formStorage);
    }
    this.changeDetectorRef.detectChanges();
  }

  saveForm() {
    console.log('submitted');
    this._storage.set(FILTER_FORM_STORAGE_KEY, this.formGroup.value);   
  }
}

working DEMO.

like image 83
Fateme Fazli Avatar answered Mar 27 '26 20:03

Fateme Fazli


We can't able to view the source code in stackblitz. The issue is you are updating the component object after DOM has been updated. You need to manually trigger the change detection to update DOM as well. use

setTimeout(()=>{

}, 0);
like image 22
Suresh Kumar Ariya Avatar answered Mar 27 '26 21:03

Suresh Kumar Ariya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!