NG0100: ExpressionChangedAfterItHasBeenCheckedError on full option table sort paginator Filter services

Viewed 24

I have an application that retrieves a list that fills a table and on the table there is a general filter, and by header suddenly with FormControl, sorting, front pagination and hide column.

So with all it's an error/NG0100 that I can't remove.

The error and causes by this.getDisplayedColumns().

try to move this function in many place but be the error or the hide column doesn't work

ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'name,...'. Current value: 'name,...
export class DomTableComponent implements OnInit, AfterViewInit {

  filterValues: any = {name:'',...};
  filterSelectObj: any[] = [];

  form:FormGroup = new FormGroup({
    name: new FormControl(true),
    ...
  });

  name = this.form.get('name');
  ...

  columnDefinitions = [
    { def: 'name', label: 'name dom', hide: !this.name!.value},
   ...
  ]

  nameFilter = new FormControl();
  ...
  globalFilter = '';

  displayedColumns: string[] = ['name',...];

  empFilters: EmpFilter[]=[];
  
  domSerice: DomService;
  dataSource= new MatTableDataSource<Dom>([]);

  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  constructor(private _httpClient: HttpClient,private _liveAnnouncer: LiveAnnouncer) {
    this.domSerice = new DomService(this._httpClient);
   }

  ngOnInit(): void {
    //this.domSerice = new DomService(this._httpClient,);
    this.domSerice.getAllDom().subscribe(x =>{
      this.dataSource = new MatTableDataSource<Dom>(x);
      this.dataSource.paginator = this.paginator;
      this.dataSource.filterPredicate = this.customFilterPredicate();
      this.dataSource.sort = this.sort;
    })

  }

  ngAfterViewInit() {
    let o1:Observable<boolean> = this.name!.valueChanges;
    ...
 
    merge(o1,o2,o3,o4,o5,o6,o7,o8).subscribe( {
      next: (v)=>{
    this.columnDefinitions[0].hide = !this.name!.value;
    ...
    //  this.getDisplayedColumns();
     }
    });
 
    //  this.getDisplayedColumns();
 
     this.nameFilter.valueChanges.subscribe((filterValue) => {
      this.filterValues['name'] = filterValue;
      this.dataSource.filter = JSON.stringify(this.filterValues);
    });
    ...
    }

    ngAfterViewChecked(){
      this.getDisplayedColumns();
    }

    announceSortChange(sortState: Sort) {
    if (sortState.direction) {
      this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
    } else {
      this._liveAnnouncer.announce('Sorting cleared');
    }

  }
  
  applyFilter(filter:any) {
    this.globalFilter = filter;
    this.dataSource.filter = JSON.stringify(this.filterValues);
    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  customFilterPredicate() {
    const myFilterPredicate = (data: Dom, filter: string): boolean => {

      var globalMatch = true;

      if (this.globalFilter) {
        globalMatch = data.name.toString().trim().toLowerCase().indexOf(this.globalFilter.toLowerCase()) !== -1 ||
        ...
        ;
      }

      let searchString = JSON.parse(filter);
      
      return globalMatch && 
      data.name.toString().trim().toLowerCase().indexOf(searchString.name) !== -1 &&
      ...;
    }
    return myFilterPredicate;
  }

  getDisplayedColumns() {
    this.displayedColumns = this.columnDefinitions.filter(cd=>!cd.hide).map(cd=>cd.def);
  }
  
}

1 Answers

you can use ChangeDetectorRef and implement AfterContentChecked in your class export

in your constructor (private changeDetectorRef: ChangeDetectorRef) and call ngAfterContentChecked() method

ngAfterContentChecked(): void { this.changeDetectorRef.detectChanges(); }

Related