Hierarchical grid Error

Hello,

after renewing Syncfusion packages to the latest version (16.2.41) hierarchical data structure not working. I can not get even my first grid level. I am getting an error:


My code looks like something like that:
grid.component.ts:

public gridData: DataManager | Object[];
public enableVirtualization: boolean = true;
public childGrid: GridModel;
public childData: Object[] = [];
public primarykey;
public parent;
public childGridLevel: number = 1;
public testArray: Object[] = [];
@Input('GridColumns') GridColumns: any;

ngAfterViewInit() {
    this.setGridDataSource();
}

public setGridDataSource() {
    if (this.IsHierarchy) {
        this.enableVirtualization = false;
        this.childData = [];

         // Find PrimaryKey and Parent fields names
        for (let i in this.GridColumns) {
            if (this.GridColumns[i].isPrimaryKey)
                this.primaryKey = this.GridColumns[i].[field];
            if (this.GridColumns[i].IsParentColumn)
                this.parent = this.GridColumns[i].field
        }

        var angularObj = this;
        // Get first level grid (where parent value is null)
        this.Service.getDataManager('someUrl').executeQuery(new Query().where(this.parent, "equal", null, true)).then((e: any) => {
            // Add additional values for later to add childGrids
            for (let k in e.result) {
                e.result[k]["NewKeyValue"] = e.result[k][this.primarykey];
                e.result[k]["NewKeyValueParent"] = e.result[k][this.parent];
            }

            this.gridData = this.childData = e.result;
            for (let i in e.result) {
                if (e.result[i].HasChildren) {
                    this.childGrid = {
                        columns: this.GridColumns,
                        queryString: "NewKeyValue",
                        detailDataBound: function (args: DetailDataBoundEventArgs) {
                                angularObj.detailDataBound(args);
                        }
                    }
                    break;
                }
            }
        })
    }
}

public detailDataBound(args: DetailDataBoundEventArgs): void {
    var grid = (args.detailElement.querySelector('.e-grid') as any).ej2_instances[0];
    // Find childGrid query selector name by child grid level
    if (this.childGridLevel % 2 == 0) {
        this.childGridLevel += 1;
        this.makeChildGrid(args.data["NewKeyValue"], grid, false);
    }
     else
    {
        this.childGridLevel += 1;
        this.makeChildGrid(args.data["NewKeyValueParent"], grid, true);
    }

    grid.DataSource = this.testArray;
}

public makeChildGrid(idVal, grid, isEven) {
    if (isEven) {
        this.Service.getDataManager('someUrl').executeQuery(new Query().where(this.parent, "equal", idVal, true)).then((e: any) => {
            var testArr: Object[] = [];
            testArr = e.result;

            for (let k in e.result) {
                e.result[k]["NewKeyValue"] = e.result[k][this.parent];
                e.result[k]["NewKeyValueParent"] = e.result[k][this.primarykey];
            }
            this.testArray = testArr;

            var angularObj = this;

            for (let i in e.result) {
                if (e.result[i].HasChildren) {
                    grid.childGrid = {
                        columns: this.GridColumns,
                        queryString: "NewKeyValueParent",
                        detailDataBound: function (args: DetailDataBoundEventArgs) {
                                angularObj.detailDataBound(args);
                        }
                    }
                    break;
                }
            }
       });
    }
    else
    {
        this.Service.getDataManager('someUrl').executeQuery(new Query().where(this.primaryKey, "equal", idVal, true)).then((e: any) => {
            var testArr: Object[] = [];
            testArr = e.result;

            for (let k in e.result) {
                e.result[k]["NewKeyValue"] = e.result[k][this.primarykey];
                e.result[k]["NewKeyValueParent"] = e.result[k][this.parent];
            }
            this.testArray = testArr;

            var angularObj = this;

            for (let i in e.result) {
                if (e.result[i].HasChildren) {
                    grid.childGrid = {
                        columns: this.GridColumns,
                        queryString: "NewKeyValue",
                        detailDataBound: function (args: DetailDataBoundEventArgs) {
                                angularObj.detailDataBound(args);
                        }
                    }
                    break;
                }
            }
       });
    }
}

grid.component.html:
<ejs-grid #grid
    [dataSource]="gridData"
    [childGrid]="childGrid"
    [enableVirtualization]="enableVirtualization"
    [columns]="GridColumns"
    (detailDataBound)="detailDataBount($event)"
>
</ejs-grid>



6 Replies

RS Renjith Singh Rajendran Syncfusion Team June 28, 2018 12:07 PM UTC

Hi AC, 

Thanks for contacting Syncfusion support. 

We have analyzed the codes you have shared with us. We could see that you are using “enableVirtualization” for hierarchy Grid. We would like to inform you that Virtual scrolling is not compatible with the hierarchy features. We suspect that this is the cause for the issue you are facing. Please refer the link below, to know more about the limitations of virtualization. 

Please get back to us if you need further assistance. 

Regards, 
Renjith Singh Rajendran. 



UN Unknown Syncfusion Team June 28, 2018 12:19 PM UTC

Hello,

I can see now that with enableVirtualization = false it is correct is I set it at first. But if I set it later - it is still seeing like enableVirtualization = true.

As you can see in My example, first of all enableVirtualization=true, but in method setGridDataSource() I set it to false. I am doing something wrong that my grid con not see property changes?


UN Unknown Syncfusion Team June 30, 2018 08:36 AM UTC

Hello,

I have one more question with hierarchical grid. To get and filter data from Web API I am sending to Web API some additional parameters. Also I am filtering data to get only one childGrid data on row expand. In childGrids I am also using paging with pageSize = 50. I am adding parameters on request and doing request like code snippet below:

this.query = getAdditionalQueryParameters();
this.Service.getDataManager('someUrl').executeQuery(this.query.where(this.parent, "equal", null, true)).then((e: any) => {
            this.gridData = this.childData = e.result;

            this.query = new Query();
            this.query = getAdditionalQueryParameters();            

            for (let i in e.result) {
                if (e.result[i].HasChildren) {
                    this.childGrid = {
                        columns: this.GridColumns,
                        queryString: "NewKeyValue",
                        query: this.query,
                        pageSettings: {
                              pageSize: 50
                        }
                        detailDataBound: function (args: DetailDataBoundEventArgs) {
                                angularObj.detailDataBound(args);
                        }
                    }
                    break;
                }
            }
        })


But there is a problem, that in every reuest doing like that, I am passing to Web API onyl my additional parameters and where clause, but never passing skip and take parameters for paging and pagesetting so I am always getting all data in request. What am I doing wrong?


RS Renjith Singh Rajendran Syncfusion Team July 2, 2018 12:40 PM UTC

Hi AC, 

Query 1 : I can see now that with enableVirtualization = false it is correct is I set it at first. But if I set it later - it is still seeing like enableVirtualization = true. 
We have created a new incident under your account for this query. Please follow up the incident for future updates. 
 
Query 2 : but never passing skip and take parameters for paging and pagesetting so I am always getting all data in request. What am I doing wrong? 
We have analyzed the code examples you have shared with us. We could see that you have overridden the default query. This is why the entire data is fetch, since there won’t be any default skip  and take query.  
 
And also we could not find where and how you have passed additional parameters from the code snippets you have shared with us. Please refer the documentation below to pass additional parameters, 
 
Please get back to us if you need further assistance. 

Regards, 
Renjith Singh Rajendran. 



UN Unknown Syncfusion Team September 10, 2018 12:27 PM UTC

Hello,

I am trying to get in child grid data all needed parameters. I am executing query like this:

this.Service.getDataManager('someUrl', true)
.executeQuery(this.requestQuery.where(this.fieldName, "equal", idValue, true).requiresCount().page(1, 20))
.then((e: any) => { /* some code */ }

Or other variant:

this.Service.getDataManager('someUrl', true)
.executeQuery(this.requestQuery.where(this.fieldName, "equal", idValue, true).requiresCount().skip(0).take(20))
.then((e: any) => { /* some code */ }

In this case I am getting from WebAPI parameter count and data. I am expecting to get pages in grid pager and to see all data count in it, but I am getting every time only one page with maximum data count 20. What I am doing wrong?

Grid pager:

Data from WebAPI on this request:

In this case I want to have 25 pages and see - 1 of 25 pages (499 items).

Maybe I need to use Pager component instead of using default grid pager?

Also, I did not mentioned it before - I want my data to be loaded dynamically when I choose with page to show.



HJ Hariharan J V Syncfusion Team September 19, 2018 08:54 AM UTC

Hi AC, 

We have validated the reported issue and we need to pass “count and result” format while return the data source to child grid. Please find the code example and sample for your reference. 

Code example 


[fetchdata.component.html] 
<ejs-grid #grid [dataSource]='parentData' [childGrid]='childGrid' [editSettings]='editSettings' [toolbar]='toolbar' [allowPaging]='true' [filterSettings]='filterOptions'> 
    <e-columns> 
        <e-column field='ID' isPrimaryKey=true headerText='ID' textAlign='Right' width=120></e-column> 
        <e-column field='CustomerID' headerText='CustomerID' width=150></e-column> 
        <e-column field='ShipCountry' headerText='ShipCountry' width=150></e-column> 
    </e-columns> 
</ejs-grid> 
 
[fetchdata.component.ts] 
 
export class FetchDataComponent { 
   . . . 
    public childGrid: any; 
    public ChildData: DataManager | Object[]; 
 
. . . 
 
    ngOnInit(): void { 
. . . 
        this.parentData = new DataManager({ 
            url: 'Home/UrlDatasource', 
            adaptor: new UrlAdaptor 
        }); 
        this.ChildData = new DataManager({ 
            url: 'Home/ChildUrl', 
            adaptor: new UrlAdaptor 
        }); 
        this.childGrid = { 
            dataSource: this.ChildData, 
            allowPaging: true, 
            pageSettings: {pageSize:5}, 
            queryString: 'ID', 
            columns: [ 
                { field: 'ID', headerText: 'ID', textAlign: 'Right',  width: 120 }, 
                { field: 'Permissions', headerText: 'Permissions', width: 150 } 
            ] 
        }; 
    } 


[Home controller.cs] 

        public IActionResult UrlDatasource([FromBody]DataManagerRequest dm) 
        { 
            var order = OrdersDetails.GetAllRecords(); 
            var Data = order.ToList(); 
            int count = order.Count(); 
            return dm.RequiresCounts ? Json(new { result = Data.Skip(dm.Skip).Take(dm.Take), count = count }) : Json(Data); 
        } 
        public IActionResult ChildUrl([FromBody]DataManagerRequest dm) 
        { 
            var order = ChildDetails.GetAllRecords(); 
            var Data = order.ToList(); 
 
            if (dm.Where != null) 
            { 
                Data = ChildDetails.GetAllRecords().Where(or => or.ID.ToString() == dm.Where[0].value.ToString()).ToList(); 
            } 
            int count = Data.Count(); 
            return Json(new { result = Data.Skip(dm.Skip).Take(dm.Take), count = count }); 
        } 





In this sample we have used ‘UrlAdaptor’ for Grid data binding . if you used another ways of data binding , please refer the following documentation and return the data format properly. 



Please install the followings in before running a sample: 

  • npm install
  • npm install @syncfusion/ej2-ng-grids --save

Regards, 
Hariharan 


Loader.
Up arrow icon