Aruna101
Aruna101

Reputation: 107

ExpressionChangedAfterItHasBeenCheckedError when using a child component inside a splitter panel

I have an Angular module that contains two Syncfusion components: MySplitterComponent and MyTreeGridComponent. MySplitterComponent defines a splitter layout and MyTreeGridComponent defines a TreeGrid using the Syncfusion Essential JS 2 TreeGrid component.

I see this ExpressionChangedAfterItHasBeenCheckedError in my console](https://i.sstatic.net/J8hx3.png)

  1. Delaying the initialization of MyTreeGridComponent using the **AfterViewInit ** and setTimeout(() => { ... }, 0) for data source binding.

  2. Used ngAfterViewInit to initialize your component properties

Non of above worked.

I have created a minimal, reproducible example below. stackblitz sample

Seeking community help to figure out what is going wrong here.

Splitter Component :

@Component({
  selector: 'my-splitter',
  template: ` <div
    id="container"
    style="height: 100%;">
    <ejs-splitter height="100%">
      <e-panes>
        <e-pane size="200px">
          <ng-template #content>
            <h3>1</h3>  
          </ng-template>
        </e-pane>
        <e-pane>
          <ng-template #content>
            <my-treegrid></my-treegrid>
          </ng-template>
        </e-pane>
      </e-panes>
    </ejs-splitter>
  </div>`,
})
export class MySplitterComponent {
  constructor() {}
}

Treegrid Component :

@Component({
  selector: 'my-treegrid',
  template: `
  <ejs-treegrid [dataSource]='data' [treeColumnIndex]='1' hasChildMapping='isParent' parentIdMapping='ParentItem' idMapping='TaskID' 
    [allowPaging]="true"
    [toolbar]="toolbar"
    >
        <e-columns>
            <e-column field='TaskID' headerText='Task ID' width='90' textAlign='Right'></e-column>
            <e-column field='TaskName' headerText='Task Name' width='170'></e-column>
            <e-column field='StartDate' headerText='Start Date' width='130' format="yMd" textAlign='Right'></e-column>
            <e-column field='Duration' headerText='Duration' width='80' textAlign='Right'></e-column>
        </e-columns>
      </ejs-treegrid>`,
})
export class MyTreeGridComponent implements OnInit, AfterViewInit {
  public data: DataManager;
  public toolbar = ['Search'];

  constructor(private cdr: ChangeDetectorRef) {}

  ngOnInit(): void {}

  ngAfterViewInit() {
    setTimeout(() => {
      this.toolbar = ['Search'];
      this.data = new DataManager({
        url: 'https://ej2services.syncfusion.com/production/web-services/api/SelfReferenceData',
        adaptor: new WebApiAdaptor(),
        crossDomain: true,
      });
      this.cdr.detectChanges();
    }, 0);
  }
}

Both components are declared in AppModule root module

@NgModule({
  declarations: [AppComponent, MySplitterComponent, MyTreeGridComponent],
  imports: [CommonModule, BrowserModule, SplitterModule, TreeGridModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Upvotes: 0

Views: 123

Answers (1)

user21731562
user21731562

Reputation: 1

The reported problem can resolved by invoking setTimeout function with certain delay from both TreeGrid and Splitter components. Refer to the code below:-

Splitter.component.ts

ngAfterViewInit()
{
    setTimeout(() =>
    {
        const componentFactory =
          this.componentFactoryResolver.resolveComponentFactory(
            MyTreeGridComponent
          );
        // add the component to the view
        const componentRef = this.container.createComponent(componentFactory);
    }, 0);
}

Modified sample link:- https://stackblitz.com/edit/angular-wmmmdc-uchi39?file=src%2Fcomponents%2Ftreegrid.component.ts

Screenshot :- 1

Upvotes: 0

Related Questions