Unable to loop through json object in nodejs [duplicate] - javascript

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 8 years ago.
I am trying to loop though a JSON object in NODEJS.
I am trying to retrieve the value of for example var value = [table][row][0][STATE] or [table][row][1][STATE] or [table][row][2][STATE] but i am getting STATE undefined error ? Is this the correct way of looping through Json object ?
data = JSON.parse(buffer);
for (var obj in data) {
if (data.hasOwnProperty(obj)) {
console.log(obj);
if (obj == "table") {
for (var prop in data[obj]) {
if (data[obj].hasOwnProperty(prop)) {
console.log(prop + ':' + data[obj][prop][0]['STATE']);
console.log(prop + ':' + data[obj][prop][1]['STATE']);
console.log(prop + ':' + data[obj][prop][2]['STATE']);
console.log(prop + ':' + data[obj][prop][0]['COUNT']);
console.log(prop + ':' + data[obj][prop][0]['COUNT']);
console.log(prop + ':' + data[obj][prop][0]['COUNT']);
}
}
}
}
}
JSON FILE
{
"table":[
{
"row":[
{
"STATE":"A"
},
{
"COUNT":"107"
}
]
},
{
"row":[
{
"STATE":"I"
},
{
"COUNT":"92"
}
]
},
{
"row":[
{
"STATE":"R"
},
{
"COUNT":"2"
}
]
}
]
}

Definitely some odd decisions in your looping. But, try this:
var json = {
"table":[
{ "row":[
{"STATE":"A"},
{"COUNT":"107"}
]
},
{ "row":[
{"STATE":"I"},
{"COUNT":"92"}
]
},
{ "row":[
{"STATE":"R"},
{"COUNT":"2"}
]
}
]
};
var table = json.table;
for( var row in table ) {
for( var field in table[row] ) {
console.log( 'State: ' + table[row][field][0].STATE);
console.log( 'Count: ' + table[row][field][1].COUNT);
}
}
Working jsfiddle: http://jsfiddle.net/pamsvofz/
Update: I'd like to add there really isn't a reason to have the additional row key in the JSON. It really just makes the nesting a little more complicated.

Related

javascript convert JSON string to JSON object

I al using javascript and looping through the values of a submitted form and trying to build a son object out of the form values.
This is an example of the final object I need:
{
"DataObject": {
"user": { "-name": "username" },
"contentFile": {
"-filename": "Breaking_News",
"lock": { "-fileIsBeingEdited": "false" },
"content": {
"line": [
{
"-index": "1",
"-text": "this is the header"
},
{
"-index": "2",
"-text": "this is the first line"
},
{
"-index": "3",
"-text": "this is the second line"
}
]
}
}
}
}
So far i am adding all of this data to a string as that seems to be the only way i can insert the form values (the line array) into the middle of the object.
var jsonStr = '{'
+ 'iceteaDataObject: {'
+ 'user: {"-name": "hindsc52"},'
+ 'contentFile: {'
+ '"-filename": "Ticker",'
+ 'lock: { "-fileIsBeingEdited": "false" },'
+ 'content: {'
+ 'line: ['
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
jsonStr += '{'
jsonStr += "-index: " + i + ',';
jsonStr += "-text: " + elem[i].value;
jsonStr += '},'
}
}
jsonStr += ']}}}}';
console.log(JSON.parse(jsonData));
however when running this I get the error: unexpected token 'i'.
I have tried to use stringily but then just outputs the entire sting again.
You don't need or want JSON for this, just build the object:
// Sample data
var elem = [{
value: "one"
}, {
value: "two"
}];
// Build the object
var obj = {
"DataObject": {
"user": {
"-name": "username"
},
"contentFile": {
"-filename": "Breaking_News",
"lock": {
"-fileIsBeingEdited": "false"
},
"content": {
"line": []
}
}
}
};
var line = obj.DataObject.contentFile.content.line;
elem.forEach(function(entry, index) {
if (entry.value != '') {
line.push({
"-index": index,
"-text": entry.value
});
}
});
// Show result:
document.body.innerHTML =
"<pre>" +
JSON.stringify(obj, null, 2) +
"</pre>";
Side note: You don't check for blank strings like this:
if (!entry.value == '') { // <== Incorrect
You can use:
if (entry.value != '') {
or:
if (entry.value) {
You shouldn't build JSON like this, but use JSON.stringify() (see MDN doc) instead:
var myObject={foo:"bar"};
var myJSON=JSON.stringify(myObject);
console.log(myJSON); //echo {"foo":"bar"}
Here is an alternative way:
var json = {
iceteaDataObject: {
"-name": "hindsc52"
},
contentFile: {
"-filename": "Ticker",
lock: { "-fileIsBeingEdited": "false" },
content: {line: []}
}
}
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
json.contentFile.content.line.push({"-index": i,"-text": elem[i].value }
}
}
var jsonStr = JSON.stringify(json);
You need to put all your keys in quotes for this to work. As the others have pointed out though, you are not really supposed to do this.
If you still want to do it your way, try this:
var jsonStr = '{'
+ '"iceteaDataObject": {'
+ '"user": {"-name": "hindsc52"},'
+ '"contentFile": {'
+ '"-filename": "Ticker",'
+ '"lock": { "-fileIsBeingEdited": "false" },'
+ '"content": {'
+ '"line": ['
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
jsonStr += '{'
jsonStr += '"-index": ' + i + ',';
jsonStr += '"-text": ' + '"' + elem[i].value + '"';
jsonStr += '},'
}
}
jsonStr += ']}}}}';

Too much recursion error on firefox jquery

I'm getting too much recursion error at the following piece of code, when I'm running the application on Firefox. The code is expected to create a graphical tree structure in the browser. The method take a Json as an input, traverses through the keys and checks if the value corresponding to the key is "Leaf". If the value is "Leaf", it displays it on the browser and moves on to the next key, else it traverses recursively through the child nodes till the "Leaf" is reached. The node with all its children are displayed on the browser:
function createmasterJson(data) {
var json = '';
for (var index in data) {
var child = data[index];
if (child == 'Leaf') {
json = json + createLeafNode(index);
} else {
if (child.length) {
for (var i = 0; i < child.length; i++) {
json = json + createNonLeafNode(index, createmasterJson(child[i]));
}
} else {
json = json + createLeafNode(index);
}
}
}
return json;
}
function createLeafNode(index){
return '{ "attributes": { "id" :"' + index + '_' + Math.random() +'"}, "data": " '+ index +'" },';
}
function createNonLeafNode(index, child){
return '{ "attributes": { "id" :"' + index + '_' + Math.random() +'"}, "data": " '+ index +'" ,"state": "closed", "children" : ['+child.substring(0, child.length - 1)+']},';
}

Creating a property inside of an object that can be continuously used

I'm the type of person who loves to do a lot of projects especially if it involves only JavaScript since that is my strong point.
I thought of a little fun idea. Writing little pieces of CSS with JavaScript. These CSS pieces could then be used in a Blob or implemented into the webpage some other way.
Most of the time, I do projects just for FUN and for build up in experience.
Let's get more of a feel for what we are working with. One of these JavaScript stylesheets could look like this:
var sheet = {
"h1": {
"font-size": "24px",
"color": "blue",
children: {
"a": {
"font-size": "15px"
}
}
},
"a": {
color: "red"
}
};
This would return:
h1{font-size:24px;color:blue}h1 a{font-size:15px}a{color:red}
Note the children propert in the h1 element.
This is my way of nesting, making the h1 a.
My question however is, how could I make a continuous nesting so I could end up with something like:
"h1 div span a"
Meaning that each nested child will need be able to use the children property.
The script I have so far is below (belongs with the variable sheet).
var to = "";
for (var el in sheet) {
var props = [];
for (var prop in sheet[el]) {
if(prop != "children") {
props.push(prop + ":" + sheet[el][prop]);
}
}
to += el + "{" + props.join(";") + "}";
//----
if (sheet[el].children) {
for (var el2 in sheet[el].children) {
var props = [];
for (var prop in sheet[el].children[el2]) {
props.push(prop + ":" + sheet[el].children[el2][prop]);
}
to += el + " " + el2 + "{" + props.join(";") + "}"
}
}
//----
}
The sections in between the comments is the code I use for the 1 time nesting.
I'm not sure how difficult this would be to add. But I understand that it probable wouldn't be easy.
My full example is here: http://jsfiddle.net/shawn31313/2tfnz/1
You can pretty easily make your code recursive:
function buildCSS(stub, node){
var to = "";
for (var el in node) {
var rule = stub + " " + el;
var props = [];
for (var prop in node[el]) {
if(prop != "children") {
props.push(prop + ":" + node[el][prop]);
}
}
to += rule + "{" + props.join(";") + "}";
if (node[el].children) {
to += buildCSS(rule, node[el].children);
}
}
return to;
}
var to = buildCSS("", sheet);
This can definitely be cleaned up, but it illustrates the idea.
http://jsfiddle.net/2tfnz/3/
You might also consider a tweak to your object structure to make the code a bit cleaner:
var sheet = {
"h1": {
rules: {
"font-size": "24px",
"color": "blue"
},
children: {
"a": {
rules: {
"font-size": "15px"
}
}
}
},
"a": {
rules: {
color: "red"
}
}
};
In this way, you wouldn't need to distinguish between properties named children and those which aren't.
http://jsfiddle.net/2tfnz/6/
Put the code in a method so it can recursively call itself when it finds children. This one allows for both children and descendant properties and outputs nicely formatted CSS.
var sheet = {
"h1": {
"font-size": "24px",
"color": "blue",
children: {
"a": {
"font-size": "15px",
descendants: {
"span": {
"font-weight": "bold"
}
}
}
}
},
"a": {
color: "red"
}
};
function toCSS(obj, pre) {
var str = '', pre = pre || '';
for (var selector in obj) {
str += pre + selector + ' {\n';
var rules = obj[selector];
for (var ruleKey in rules) {
if (['descendants', 'children'].indexOf(ruleKey) > -1) continue;
str += ' ' + ruleKey + ': ' + rules[ruleKey] + ';\n';
}
str += '}\n\n';
if ('descendants' in rules) str += toCSS(rules.descendants, pre + selector + ' ');
if ('children' in rules) str += toCSS(rules.children, pre + selector + ' > ');
}
return str;
}
console.log(toCSS(sheet));
I like all of you guy's code. However, I told the idea of making my code recursive.
So I've made:
var to = "";
for (var el in sheet) {
var props = [];
var nest = [el];
var nestLookUp = {
"children": ">",
"desendents": ""
};
var nests = /children|desendents/;
var addNest = function (shh) {
for (var found in nestLookUp) {
if (shh.hasOwnProperty(found)) {
for (var el2 in shh[found]) {
var props = [];
nest.push(nestLookUp[found]);
nest.push(el2);
for (var prop in shh[found][el2]) {
if (!prop.match(nests)) {
props.push(prop + ":" + shh[found][el2][prop]);
}
}
if (props.length > 0) {
to += nest.join(" ").replace(/\s{2}/, " ") + "{" + props.join(";") + "}";
}
addNest(shh[found][el2]);
nest.pop();
nest.pop();
};
}
}
};
for (var prop in sheet[el]) {
if (prop != "children") {
props.push(prop + ":" + sheet[el][prop]);
}
}
to += el + "{" + props.join(";") + "}";
addNest(sheet[el]);
}
#Trevor - Your Idea with the descendants, is a good one :)
My code is a little longer than Trevors but personally more manageable. (39 lines his is 20)
I usually like making my own code because I usually understand how the code works.
Ha, I was a little confused looking at you guys code.

jQuery Nested Array..get immediate parent id

I have the following array
array = [
{
"id": "67",
"sub": [
{
"id": "663",
},
{
"id": "435",
}
]
},
{
"id": "546",
"sub": [
{
"id": "23",
"sub": [
{
"id": "4",
}
]
},
{
"id": "71"
}
]
}
]
I am currently looping throught the array as follows
calling the array:
processArray(array);
the function loop
function processArray(arr)
{
for(var item in arr) {
var value = arr[item];
var order = item;
var itemID = value.id;
if(itemID != null)
{
$('.text').append(" ORDER : " + order + " Item ID : " + itemID + "<br />" );
}
if(typeof(value) == 'object') { //If it is an array,
processArray(arr[item]);
}
}
}
Currently i am getting the order of the item and the current ID no problem. What i need however (for my database schema) is for each item get the ID of its parent if there is one.
Do i need to pass the parent to each node? Or is there an easier way?
Thanks
Working demo
Include an optional parameter parentID in the function; by doing this, you can still use the processArray(array); syntax to process the original array.
function processArray(arr, parentID)
{
for(var item in arr) {
var value = arr[item];
var order = item;
var itemID = value.id;
if(itemID != null)
{
var output = " ORDER : " + order + " Item ID : " + itemID;
if( parentID ) { output += " PARENT : " + parentID; }
$('.text').append( output + "<br />");
}
// PROCESS SUB-ARRAY
if( typeof(value.sub) == 'object') { //If it is an array,
processArray( value.sub, itemID );
}
}
}
Use an auxiliary function that has id as part of its signature:
function processArray(arr) {
function _processArray(arr, id) {
for (var item in arr) {
var value = arr[item];
var order = item;
var itemID = value.id; // you need to change this because on the second call you pass in a string and not just an object
var parentId = id;
// Commenting the if statement that you had here actually shows the parent id's now.
$('.text').append(" ORDER : " + order + " Item ID : " + itemID + " Parent Id : " + parentId + "<br />");
if (typeof value === "object") { //use instanceof,
_processArray(arr[item], itemID);
}
}
}
_processArray(arr, 0);
}

Iterating json array in javascript

after looking through a lot of similar questions on SO, I still can't iterate my json structure. How can I reach the value (key) of my inner array?
var data = {"User1":{"Service1":2,"Service2":1},"User2":{"Service3":1}}
for(var user in data) {
document.write(user + ': ')
for(var service in data[user]){
document.write(service + ': ' + user[service])
}
document.write("<br />")
}
This prints:
User1: Service1: undefined Service2: undefined
User2: Service3: undefined
And I'd like it to print
User1: Service1: 2 Service2: 1
User2: Service3: 1
Is javascript enough or do I need jQuery?
Thanks in advance!
var data = {
User1: {
Service1: 2,
Service2: 1
},
User2: {
Service3: 1
}
};
for (var user in data) {
console.log("User: " + user);
for (var service in data[user]) {
console.log("\tService: " + service + "; value: " + data[user][service]);
}
}
Replace console.log with document.write or whatever.
document.write(service + ': ' + data[user][service])

Categories

Resources