Displaying a complex object with DataGrid

Suppose you have the following data source:

  "dataSource": ejs.data.DataUtil.parse.isJson([
  {
    "EmployeeId": "123456789",
    "FirstName": "Darth",
    "LastName": "Vader",
    "Bo2": [
      {
        "Address1": "This is child 1 address 1",
        "Address2": "This is child 1 address 2"
      },
      {
        "Address1": "This is child 2 address 1",
        "Address2": "This is child 2 address 2"
      }
    ]
  }

How would you create a grid to display the values of the EmployeeId, FirstName, LastName, and the two Bo2 objects (Address1 and Address2)?  



9 Replies

SK Sujith Kumar Rajkumar Syncfusion Team July 30, 2020 06:41 AM UTC

Hi Scot, 

Greetings from Syncfusion support. 

We checked your query and would like to let you know that you can achieve your requirement of performing complex data binding to the Grid columns using the dot(.) operator in the field name. For array data you can directly specify it as “Bo2.Address1” and for object array data you can access them like, “Bo2.0.Address1” & “Bo2.0.Address2”

So you can perform the complex binding for the provided data as demonstrated in the below code snippet, 

<e-column field='Bo2.0.Address1' headerText='Address 1'></e-column> 
<e-column field='Bo2.0.Address2' headerText='Address 2'></e-column> 

More details on this can be checked in the below help documentation links, 


Complex data binding with array of objects documentation: https://ej2.syncfusion.com/aspnetcore/documentation/grid/how-to/list-of-array-of-objects/ 

Please get back to us if you require any further assistance. 

Regards, 
Sujith R 



SW Scot Woodyard July 30, 2020 09:40 PM UTC

What about Address2, and iterating through so that both Address1 and Address2 are shown?


SK Sujith Kumar Rajkumar Syncfusion Team July 31, 2020 06:16 AM UTC

Hi Scot, 
 
You can access the Address2 property in the object’s first array as “field=’Bo2.0.Address2’” and second array as “field='Bo2.1.Address2'” as mentioned in our previous update. So the “Address1” and “Address2” arrays in the “Bo2” object of the data that you have mentioned can be accessed like below, 
 
// Accessing the ‘Bo2’ object’s first array data 
<e-column field='Bo2.0.Address1' headerText='Address 1_1'></e-column>  
<e-column field='Bo2.0.Address2' headerText='Address 2_1'></e-column>  
// Accessing the ‘Bo2’ object’s second array data 
<e-column field='Bo2.1.Address1' headerText='Address 1_2'></e-column>  
<e-column field='Bo2.1.Address2' headerText='Address 2_2'></e-column>  
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



SW Scot Woodyard July 31, 2020 10:09 PM UTC

What is the proper way to iterate through both?


SK Sujith Kumar Rajkumar Syncfusion Team August 3, 2020 01:08 PM UTC

Hi Scot, 
 
You can iterate through the data and based on that form the columns for complex object and then push it to the Grid columns to achieve your requirement. This is demonstrated in the below code snippet, 
 
// Grid’s load event handler 
function onLoad() { 
        // Data that is bound to the Grid 
        var data = @Html.Raw(Json.Serialize(ViewBag.Data)); 
        // The complex data is retrieved from the data to form the columns 
        // This is performed considering all the data array has same complex object so the first data object alone is retrieved 
        // If there are different complex data then you need to iterate through each data and retrieve its corresponding complex object and for that you need to perform the below operation 
        var complexObj = data[0].Bo2; 
        var complexCols = []; 
        // Column object is formed based on the complex data object 
        complexObj.forEach((x, index) => { 
            if (x.Address1) complexCols.push({ field: "Bo2." + index.toString() + ".Address1" }); if (x.Address2) 
                complexCols.push({ field: "Bo2." + index.toString() + ".Address2" }) 
        }); 
        // Each complex data column formed is pushed to the Grid column model 
        complexCols.forEach(x => this.columns.push(x)); 
} 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



SW Scot Woodyard August 4, 2020 12:22 AM UTC

Thank you for your help - I actually need to iterate through and display the data as rows like this:

EmployeeIdFirstNameLastNameAddress1Address2
123456789DarthVaderThis is child 1 address 1
This is child 1 address 2

123456789Darth VaderThis is child 2 address 1
This is child 2 address 1

What is the best way to accomplish that?



SK Sujith Kumar Rajkumar Syncfusion Team August 4, 2020 09:42 AM UTC

Hi Scot, 
 
We checked your query and would like to let you know that for achieving this requirement you need to use the columns valueAccessor property. The valueAccessor is used to access/manipulate the value of display data and so with this you can achieve custom value formatting. This is demonstrated in the below code snippet for your data scenario, 
 
@{ 
    var address1 = "valueAccessorFn1"; 
    var address2 = "valueAccessorFn2"; 
} 
 
<div id="parent"> 
     
    <ejs-grid id="Grid" dataSource="@ViewBag.Data"> 
        <e-grid-columns> 
                   . 
                   . 
            <e-grid-column headerText="Address 1" valueAccessor="address1" width="120"></e-grid-column> 
            <e-grid-column headerText="Address 2" valueAccessor="address2" width="120"></e-grid-column> 
        </e-grid-columns> 
    </ejs-grid> 
 
</div> 
<script> 
    var index1 = 0; 
    var index2 = 0; 
 
    // Custom formatted value to be displayed in the Address1 column 
    function valueAccessorFn1(field, data, column) { 
        // Data is accessed from the object array based on an index value 
        var value = data.Address[index1].Address1; 
        // The index value is incremented so that the next index can be accessed for the consecutive rows 
        index1++; 
        // Value to be displayed is returned 
        return value; 
    } 
 
    // Custom formatted value to be displayed in the Address2 column 
    function valueAccessorFn2(field, data, column) { 
        // Data is accessed from the object array based on an index value 
        var value = data.Address[index2].Address2; 
        // The index value is incremented so that the next index can be accessed for the consecutive rows 
        index2++; 
        // Value to be displayed is returned 
        return value; 
    } 
</script> 
 
This will display the following result in the Grid, 
 
 
 
We have prepared a sample based on this for your reference, 
 
 
 
Note: The value accessor is used only for modifying the display data. The grid actions like, filtering, sorting, etc. cannot be performed based on this. 
 
Regards, 
Sujith R 



SW Scot Woodyard August 5, 2020 12:06 AM UTC

I applied what you sent me to a sample project, but I must be missing something because as soon as I add the "valueAccessor" tag to one of the columns the grid stops displaying.  I've attached the project.

Attachment: GridPrototpye2_ad048bfa.zip


SK Sujith Kumar Rajkumar Syncfusion Team August 5, 2020 10:03 AM UTC

Hi Scot, 
 
The reported problem was occurring because the data was not properly returned from the value accessor function in the shared sample application as shown in the below image, 
 
  
 
You can resolve this by returning the value from the value accessor function(For the data bound in the shared sample application) as demonstrated in the below code snippet, 
 
// Custom formatted value to be displayed in the Address1 column 
function valueAccessorFn1(field, data, column) { 
            // Data is accessed from the object array based on an index value 
            //var value = data.Address[index].Employees[0].Division; 
            var value = data.Employees[0].Division; 
            // The index value is incremented so that the next index can be accessed for the consecutive rows 
            index++; 
            // Value to be displayed is returned 
            return value; 
} 
 
We have modified the shared sample based on this. You can download it from the following link, 
 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 


Loader.
Up arrow icon