How do I render JSON in tree like way just like http://jsonviewer.stack.hu/ does using angular JS?
I wrote a function to display a JSON data in the angular-ui-tree component.
The key point is the following:
In your parse routine, keep the 'JSON string' of the current node in the node itself, every 'not parsed' node has this payload and a 'load' function.
function parse(name, value) {
var node = {
name: name
};
if (Array.isArray(value)) {
node.isEmpty = value.length === 0;
node.payload = value;
node.props = [];
node.load = function(node) {
for (var i = 0; i < node.payload.length; i++) {
node.props.push(parse(node.name + '[' + i + ']', node.payload[i]));
}
delete node.isEmpty;
delete node.payload;
}
} else if (value !== undefined && value !== null && typeof value === 'object') {
node.isEmpty = Object.keys(value).length === 0;
node.payload = value;
node.props = [];
node.load = function(node) {
var keys = Object.keys(node.payload);
for (var i = 0; i < keys.length; i++) {
node.props.push(parse(node.name + '.' + keys[i], node.payload[keys[i]]));
}
delete node.isEmpty;
delete node.payload;
}
} else {
node.value = value;
}
return node;
}
Then, when the user click on the toggle button you can call this function to parse the next nodes in the tree and bind tha data to the HTML.
Can be more clear with a example: https://jsfiddle.net/MatteoTosato/ghm4z606/
The technique you are interested in is 'recursive directive'. If you don't know how to write a directive yet, then you should start learning it first. The official Angular JS doc got a lot better in explaining about directive Creating Custom Directives
Once you know how to write custom directive, you can learn about recursive directive. I found this Google Groups thread helpful: Recursive directives. Especially, I found Mark Lagendijk's Recursion Helper service in that thread very useful.
Make sure to checkout the examples there. Some relevant examples for you are:
plnkr
jsfiddle
In the jsfiddle example above, take a look at:
module.directive("tree", function($compile) {
return {
restrict: "E",
transclude: true,
scope: {family: '='},
template:
'<ul>' +
'<li ng-transclude></li>' +
'<p>{{ family.name }}</p>' +
'<li ng-repeat="child in family.children">' +
'<tree family="child"></tree>' +
'</li>' +
'</ul>',
compile: function(tElement, tAttr, transclude) {
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(scope, function(clone, scope) {
iElement.append(clone);
});
};
}
};
});
Some of the code above is abstracted away by Mark Lagendijk's Recursion Helper service I mentioned above.
Lastly, I implemented angular-json-human, which renders JSON in a nested table structure, which makes it easier for human to read. You can modify it to suit your need. The demo is here and the repo is here
Hope this helps!
I've made this Angular directive for rendering JSON in a nice way. It's available in bower:
https://github.com/mohsen1/json-formatter