displaying nested json in ag-grid
Asked Answered
C

3

6

I am using Angular Grid (ag-grid) to display data. i am trying to display nested json data in my angular grid. but i was unsuccessful.

below is the sample json data and colDefs. please suggest that why dot operator is not working unlike jqgrid, to map grid columns with nested json fields.

var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', ['$scope', '$http',
function($scope, $http) {
$scope.myData = [{
"defaultColumns1": {"region":"PA"},
"defaultColumns2": {"LocationName": "loc1",
"LegalName": "legName1"
}
},
{
"defaultColumns1": {"region":"PB"},
"defaultColumns2": {"LocationName": "loc2",
"LegalName": "legName2"
}
}];

$scope.gridOptions = {
  data: 'myData',
  columnDefs: [{
    field: 'defaultColumns1.region',
    displayName: 'Region'
  }, {
    field: 'defaultColumns2.LocationName',
    displayName: 'Location',
    headerGroup: 'address'
  }, {
    field: 'defaultColumns2.LegalName',
    displayName: 'Legal Name',
    headerGroup: 'address'
  }],
  enableColumnResize: true,
  groupHeaders : true
}
}]);

index.html

<!DOCTYPE html>
<html ng-app="myApp">

<head lang="en">
<meta charset="utf-8" />
<title>Custom Plunker</title>
<link  rel="stylesheet" href="../dist/ag-grid.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.js">   </script>
<script src="http://code.angularjs.org/1.2.15/angular.js"></script>
<script  src="../dist/ag-grid.min.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"   rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="style.css" />

<script type="text/javascript" src="main.js"></script>
</head>

<body ng-controller="MyCtrl">
<div class="gridStyle" ag-grid="gridOptions"></div>
</body></html>
Cocoa answered 30/9, 2015 at 8:43 Comment(5)
Your html pls. A plunkr would be great help.Fowl
@Fowl i have added the html code. kindly, have a lookCocoa
im badly struck at this point. can somebody suggest me workaround for my issue. it would be a great help..Cocoa
can you create a fiddle o plunkrFowl
plnkr.co/edit/mVOIYly9BKFtBC4CJtrY?p=previewCocoa
F
0

There were a few issues with the way you went through your data. $scope.myData is an array of objects, therefore you need to either iterate over it or dig data by index. Also your $scope.gripOptions was not quite right. I just followed the ag-grid docs

Take a look at this updated plunker. The code is pretty basic but it does what I think you want. You can always create a function to iterate over the array (leave that as homework :-))

$scope.myData = [{
  "defaultColumns1": {
    "region": "PA"
  },
  "defaultColumns2": {
    "LocationName": "loc1",
    "LegalName": "legName1"
  },
  "name": "name1"
}, {
  "defaultColumns1": {
    "region": "PB"
  },
  "defaultColumns2": {
    "LocationName": "loc2",
    "LegalName": "legName2"
  },
  "name": "name2"
}];

var columnDefs = [{
  headerName: 'Region',
  field: 'region'
}, {
  headerName: 'Location',
  field: 'location'
}, {
  headerName: 'Legal name',
  field: 'legal_name'
}]

var rowData = [{
  region: $scope.myData[0].defaultColumns1.region,
  location: $scope.myData[0].defaultColumns2.LocationName,
  legal_name: $scope.myData[0].defaultColumns2.LegalName
}, {
  region: $scope.myData[1].defaultColumns1.region,
  location: $scope.myData[1].defaultColumns2.LocationName,
  legal_name: $scope.myData[1].defaultColumns2.LegalName
}, ]

$scope.gridOptions = {
  columnDefs: columnDefs,
  rowData: rowData
};

Take a look at the way $scope.gridOptions is now constructed ( as suggested in the docs.)

Hope it helps.

Fowl answered 1/10, 2015 at 8:17 Comment(5)
Thanks for your kind response. i understand your point here. i was looking for mapping json fields directly to the row data without iterating the json object as what you had explained above.. when we use jqgrid, we can directly map nested json object to rowdata by defining the path in the colDefs. i was looking for something like that. i think, ag-grid doesn't support mapping nested json object mapping.Cocoa
i get nested json object from server. just for illustration purpose, i have provided simple nested json object in my above example.Cocoa
The answer provided answers the question as originally posted. If thats the case accepting the answer is customary. If you have a different use case then you should ask a new question.Fowl
thanks for your quick response, Jax :) i will accept this answer.Cocoa
i have changed the data structure in server side and used your approach, problem is solved. Thanks much :)Cocoa
B
12

ag-grid field attribute can only refer to a property of the data row, but the valueGetter attribute allows expressions. So, while

field: 'defaultColumns1.region'

won't work, switching to

valueGetter: 'data.defaultColumns1.region'

will work fine. Sample plunker forked from yours is at http://plnkr.co/edit/8enzrjt2MQwfa8VjGaIy?p=preview

Berkin answered 24/4, 2016 at 9:32 Comment(3)
What do you suggest if defaultColumns1 is an array and all I need is defaultColumns1[0].fieldName?Cheekpiece
Simplest is probably a value getter, i.e. valueGetter: 'defaultColumns1[0].fieldName' (assuming "defaultColumns" is an array on your node.data. For more complicated work, I've found custom editors are very handy - those let you write an initializer, a gui constructor, entry and exit handlers, etc.Berkin
From what I tried doing field: 'defaultColumns1.region' will also work in latest AG-grid.Whipple
F
0

There were a few issues with the way you went through your data. $scope.myData is an array of objects, therefore you need to either iterate over it or dig data by index. Also your $scope.gripOptions was not quite right. I just followed the ag-grid docs

Take a look at this updated plunker. The code is pretty basic but it does what I think you want. You can always create a function to iterate over the array (leave that as homework :-))

$scope.myData = [{
  "defaultColumns1": {
    "region": "PA"
  },
  "defaultColumns2": {
    "LocationName": "loc1",
    "LegalName": "legName1"
  },
  "name": "name1"
}, {
  "defaultColumns1": {
    "region": "PB"
  },
  "defaultColumns2": {
    "LocationName": "loc2",
    "LegalName": "legName2"
  },
  "name": "name2"
}];

var columnDefs = [{
  headerName: 'Region',
  field: 'region'
}, {
  headerName: 'Location',
  field: 'location'
}, {
  headerName: 'Legal name',
  field: 'legal_name'
}]

var rowData = [{
  region: $scope.myData[0].defaultColumns1.region,
  location: $scope.myData[0].defaultColumns2.LocationName,
  legal_name: $scope.myData[0].defaultColumns2.LegalName
}, {
  region: $scope.myData[1].defaultColumns1.region,
  location: $scope.myData[1].defaultColumns2.LocationName,
  legal_name: $scope.myData[1].defaultColumns2.LegalName
}, ]

$scope.gridOptions = {
  columnDefs: columnDefs,
  rowData: rowData
};

Take a look at the way $scope.gridOptions is now constructed ( as suggested in the docs.)

Hope it helps.

Fowl answered 1/10, 2015 at 8:17 Comment(5)
Thanks for your kind response. i understand your point here. i was looking for mapping json fields directly to the row data without iterating the json object as what you had explained above.. when we use jqgrid, we can directly map nested json object to rowdata by defining the path in the colDefs. i was looking for something like that. i think, ag-grid doesn't support mapping nested json object mapping.Cocoa
i get nested json object from server. just for illustration purpose, i have provided simple nested json object in my above example.Cocoa
The answer provided answers the question as originally posted. If thats the case accepting the answer is customary. If you have a different use case then you should ask a new question.Fowl
thanks for your quick response, Jax :) i will accept this answer.Cocoa
i have changed the data structure in server side and used your approach, problem is solved. Thanks much :)Cocoa
L
0

Rendering nested objects as strings with cellRenderer

If e.g. for testing purposes you are fine with just displaying the nested element as string, you can check if the element is nested and just call JSON.stringify() on it. Note that in this code, I extract the keys automatically from the first element for convenience.

// Extract payload keys
const payloadKeys = Object.keys(mydata.result[0].payload);

// Custom cell renderer
function customRenderer(params) {
    const nestedKey = Object.keys(params.data.payload).find(key => typeof params.data.payload[key] === 'object');
    const value = params.data.payload[params.colDef.field.split('.')[1]];

    if (params.colDef.field.endsWith(`.${nestedKey}`)) {
        return typeof value === 'object' ? JSON.stringify(value) : value; // Render nested element as string
    } else {
        return value;
    }
}

// Update column definition
const columnDefs = [
    ...payloadKeys.map(key => ({
        headerName: key,
        field: `payload.${key}`,
        maxWidth: 300,
        editable: true,
        valueGetter: params => params.data.payload[key],
        tooltipValueGetter: (params) => params.value,
        filter: true,
        autoHeight: true,
        cellRenderer: customRenderer // Use the custom cell renderer
    })),
];

Lendlease answered 23/2 at 9:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.