Virtual scroll official examples for treepanel generating ExpressionChangedAfterItHasBeenCheckedError

705 views Asked by At

I am attempting to get virtual scroll working for the TreeTable, and after following the official examples I am getting ExpressionChangedAfterItHasBeenCheckedError when iI expand any of the nodes for my data.

When trying the official demo's with Stackblitz I see the errors are also generated here too, this is happening for both primeng v9 and v10 latest demo examples.

I noticed a GitHub issue has been raised for this also here - https://github.com/primefaces/primeng/issues/8886 but was closed with a workaround referenced to add a ChangeDetectorRef and trigger a change detection cycle manually.

I tried this solution with the official stackblitz demo's (https://stackblitz.com/edit/primeng-treetablescroll-demo?file=src%2Fapp%2Fapp.component.ts)

setTimeout(() => {
    this.virtualFiles = Array.from({length: 1000}).map((_,i) => this.createNode(i, 100));
    this.cd.detectChanges();
}, 2000);

But it makes no difference, the error is still generated, perhaps I am implementing this incorrectly?

To replicate the issue, you just have to expand one of the nodes displayed in the virtual scroll example.

I am particularly interested in a solution\workaround for primeng 9

2

There are 2 answers

5
Akash On

Update:

Some workarounds you can try -

Option 1

Change virtualRowHeight to auto - [virtualRowHeight]="auto". But this will really impact the performance of expand/collapse toggle.

Option 2

Use ChangeDetectionStrategy.OnPush strategy on your component. But be careful of its side effects (read this to know how it works). Please see this stackBlitz.

Original answer:

This issue has been fixed in the version 10.0.3. If you're curious, take a look at this commit which fixes this issue.

Also, checkout this forked stackBlitz. It works without any workaround.

0
Dipen Shah On

As mentioned by Akash, issue has been fixed in later version of the library and you check the changes attached with BUG you mentioned and can apply the fix in your code as well:

app.component.html

...
<p-treeTable #treeTable [value]="virtualFiles" [columns]="cols" [scrollable]="true
  [rows]="100">
  ...
</p-treeTable>

app.component.ts

...
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements AfterViewInit, OnDestroy { 
    @ViewChild(TreeTable)
    private virtualTable: TreeTable;

    virtualFiles: TreeNode[];
    cols: any[];
  
    private virtualTableSub: Subscription;

    constructor(
        private nodeService: NodeService,
        private primengConfig: PrimeNGConfig,
        private cdr: ChangeDetectorRef
    ) { }
    ...
    ngAfterViewInit() {
      this.virtualTable.tableService.uiUpdateSource$.subscribe(() => {
        if (this.virtualTable.virtualScroll) {
          this.cdr.detectChanges();
        }
      })
    }

    ngOnDestroy() {
      this.virtualTableSub?.unsubscribe();
    }
    ...
}

Take a look at this stackblitz.