How do I iterate over a JSON structure? [duplicate] - javascript

This question already has answers here:
Loop (for each) over an array in JavaScript
(40 answers)
Closed 5 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I have the following JSON structure:
[{ "id":"10", "class": "child-of-9" }, { "id": "11", "classd": "child-of-10" }]
How do I iterate over it using JavaScript?

var arr = [ {"id":"10", "class": "child-of-9"}, {"id":"11", "class": "child-of-10"}];
for (var i = 0; i < arr.length; i++){
document.write("<br><br>array index: " + i);
var obj = arr[i];
for (var key in obj){
var value = obj[key];
document.write("<br> - " + key + ": " + value);
}
}
note: the for-in method is cool for simple objects. Not very smart to use with DOM object.

Taken from jQuery docs:
var arr = [ "one", "two", "three", "four", "five" ];
var obj = { one:1, two:2, three:3, four:4, five:5 };
jQuery.each(arr, function() {
$("#" + this).text("My id is " + this + ".");
return (this != "four"); // will stop running to skip "five"
});
jQuery.each(obj, function(i, val) {
$("#" + i).append(document.createTextNode(" - " + val));
});

Use for...of:
var mycars = [{name:'Susita'}, {name:'BMW'}];
for (var car of mycars)
{
document.write(car.name + "<br />");
}
Result:
Susita
BMW

Please let me know if it is not easy:
var jsonObject = {
name: 'Amit Kumar',
Age: '27'
};
for (var prop in jsonObject) {
alert("Key:" + prop);
alert("Value:" + jsonObject[prop]);
}

If this is your dataArray:
var dataArray = [{"id":28,"class":"Sweden"}, {"id":56,"class":"USA"}, {"id":89,"class":"England"}];
then:
$(jQuery.parseJSON(JSON.stringify(dataArray))).each(function() {
var ID = this.id;
var CLASS = this.class;
});

Copied and pasted from http://www.w3schools.com, there is no need for the JQuery overhead.
var person = {fname:"John", lname:"Doe", age:25};
var text = "";
var x;
for (x in person) {
text += person[x];
}
RESULT: John Doe 25

mootools example:
var ret = JSON.decode(jsonstr);
ret.each(function(item){
alert(item.id+'_'+item.classd);
});

You can use a mini library like objx - http://objx.googlecode.com/
You can write code like this:
var data = [ {"id":"10", "class": "child-of-9"},
{"id":"11", "class": "child-of-10"}];
// alert all IDs
objx(data).each(function(item) { alert(item.id) });
// get all IDs into a new array
var ids = objx(data).collect("id").obj();
// group by class
var grouped = objx(data).group(function(item){ return item.class; }).obj()
There are more 'plugins' available to let you handle data like this, see http://code.google.com/p/objx-plugins/wiki/PluginLibrary

With nested objects, it can be retrieve as by recursive function:
function inside(events)
{
for (i in events) {
if (typeof events[i] === 'object')
inside(events[i]);
else
alert(events[i]);
}
}
inside(events);
where as events is json object.

Marquis Wang's may well be the best answer when using jQuery.
Here is something quite similar in pure JavaScript, using JavaScript's forEach method. forEach takes a function as an argument. That function will then be called for each item in the array, with said item as the argument.
Short and easy:
var results = [ {"id":"10", "class": "child-of-9"}, {"id":"11", "classd": "child-of-10"} ];
results.forEach(function(item) {
console.log(item);
});

this is a pure commented JavaScript example.
<script language="JavaScript" type="text/javascript">
function iterate_json(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
hr.open("GET", "json-note.php", true);//this is your php file containing json
hr.setRequestHeader("Content-type", "application/json", true);
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var data = JSON.parse(hr.responseText);
var results = document.getElementById("myDiv");//myDiv is the div id
for (var obj in data){
results.innerHTML += data[obj].id+ "is"+data[obj].class + "<br/>";
}
}
}
hr.send(null);
}
</script>
<script language="JavaScript" type="text/javascript">iterate_json();</script>// call function here

var jsonString = `{
"schema": {
"title": "User Feedback",
"description": "so",
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"options": {
"form": {
"attributes": {},
"buttons": {
"submit": {
"title": "It",
"click": "function(){alert('hello');}"
}
}
}
}
}`;
var jsonData = JSON.parse(jsonString);
function Iterate(data)
{
jQuery.each(data, function (index, value) {
if (typeof value == 'object') {
alert("Object " + index);
Iterate(value);
}
else {
alert(index + " : " + value);
}
});
}
Iterate(jsonData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Another solution to navigate through the JSON document is JSONiq (implemented in the Zorba engine), where you can write something like this:
let $doc := [
{"id":"10", "class": "child-of-9"},
{"id":"11", "class": "child-of-10"}
]
for $entry in members($doc) (: binds $entry to each object in turn :)
return $entry.class (: gets the value associated with "class" :)
You can run it on http://public.rumbledb.org:9090/public.html

Related

Why is this JSON file reading strangly

I have a JSON document here. I have validated it with JSlint.
The JSON is of this format:
[{
"date": "2017-02-10",
" action": "Do a thing",
"state": "closed",
"url": "https:someurl.com"
},
....
I have some HTML here, which exists only to read and output the JSON.
The HTML looks like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
</head>
<body>
<script>
deadlines = []
start();
function start() {
var req = new XMLHttpRequest();
req.open("GET", "http://joereddington.com/deadlines.json");
req.overrideMimeType("application/json");
req.send(null);
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
var obj = JSON.parse(req.responseText);
deadlines = obj
for (deadline in deadlines) {
var output = '';
for (var property in deadline) {
console.log(property)
output += property + ': ' + deadline[property] + '; ';
}
console.log(output);
console.log(deadline.date)
console.log(deadline.action)
}
}
};
}
</script>
</body>
However, when I try and list the properties of each object, I get very strange results:
rather than the names and values I'm looking for. Can someone tell me what I'm doing wrong?
$.each(JSON.parse(deadlines), function (index, deadline) {
var output = '';
for (var property in deadline) {
console.log(property)
output += property + ': ' + deadline[property] + '; ';
}
console.log(output);
console.log(deadline.date);
console.log(deadline.action);
});
Your JSON string contains extra space. It should be "action" not " action".
for...in loops over the keys (since it's an array: "0", "1" ...). Use for...of or forEach or a basic for loop.
I recommend forEach like this:
deadlines.forEach(function(deadline) {
// ...
});

Using jQuery, how do I select dynamic related data keys on an element and output them into an array?

For example, given this HTML:
<div class="playlist"
data-name1="Some Name 1"
data-value1="123"
data-name2="Some Name 2"
data-value2="456"
data-name3="Some Name 3"
data-value3="789"
></div>
I want to return an array of key/value pairs like so (using jQuery):
[{
"name": "Some Name 1",
"value": "123"
}, {
"name": "Some Name 2",
"value": "456"
}, {
"name": "Some Name 3",
"value": "789"
}]
Here is some pseudo code that I thought about but obviously doesn't work:
array = []
$(".playlist").attr("data-name-*, data-value-*").each(function(name, value){
array.push({"name": name, "value": value});
}
})
return array;
Any ideas?
array = []
$.each($('.playlist')[0].attributes, function(i, attrib){
array.push({name : attrib.name, value : attrib.value});
});
console.log(array);
This can give you something to work with. It works.
var attributes = $('.playlist')[0].attributes;
var total_attr = attributes.length - 1;
var test = [];
for (var i = 1; i < attributes.length; i += 2) {
var attr = attributes[i];
var value = attributes[i+1];
var temp = {};
temp['name' + i] = attr.nodeValue;
temp['value' + i] = value.nodeValue;
test.push(temp)
}
console.log(test)
var length_data = Object.keys($(".playlist").data()).length/2;
var data = []
for (i = 1; i <= length_data; i++) {
data.push({"name" : $(".playlist").attr('data-name'+i), "value" : $(".playlist").attr('data-value'+i)} )
}
DEMO here
Update
For prevent when u had more data :
var length_data = Object.keys($(".playlist").data()).length/2;
var data = []
for (i = 1; i <= length_data; i++) {
if (typeof $(".playlist").attr('data-name'+i) == "undefined" || typeof $(".playlist").attr('data-value'+i) == "undefined" ) continue;
data.push({"name" : $(".playlist").attr('data-name'+i), "value" : $(".playlist").attr('data-value'+i)} )
}
Demo update

Parsing json array to array javascript

I have an array with json data:
var jsonString=[
{
"url": "http://www.anurl.com",
"tags": {
"Event": 6,
"Event1": 2
}
}
]
Now i want to build the next structure:
var data= [ {"text":"Event", "weight" : "6", "link" :"www.anurl.com"} //etc ];
Now i looked into the var array = $.parseJSON(JSON.stringify(jsonString));
and on the result i try to build my data array with .push();
But how can i insert the Event: 6 part? i cannot do array.tags[0] as array.tags will give me both of them.
So how can i solve this problem?
You are using object literals in javascript, the example you provided:
var jsonString=[{
"url": "http://www.anurl.com",
"tags": {
"Event": 6,
"Event1": 2
}
}];
jsonString is an array, and the element tags is an object NOT an array so you can access it like this:
var event = jsonString[0].tags.Event;
You can read the attributes of the tags object like the example below :
function loadArray(urls){
xhrDoc= new XMLHttpRequest();
if (xhrDoc.overrideMimeType)
xhrDoc.overrideMimeType('text/plain; charset=x-user-defined');
xhrDoc.onreadystatechange =function()
{
if (this.readyState == 4)
{
if (this.status == 200)
{
var data= this.response; //Here is a string of the text data
printUrls(data);
}
}
};
xhrDoc.open('GET', urls , true);
xhrDoc.send();
}
function printUrls(response) {
var arr = JSON.parse(response);
var i;
var out = "";
for(i = 0; i < arr.length; i++) {
console.log(arr[i].url);
console.log(arr[i].tags['Event']); // Read Event
console.log(arr[i].tags['Event1']); //// Read Event1
out = "URL : "+ arr[i].url + " Event : "+ arr[i].tags['Event']+ " Event1 : " + arr[i].tags['Event1'] + "\n";
}
document.getElementById("id01").innerHTML = out;
}
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="parseJsonFile.js"></script>
</head>
<body onload="loadArray('parseJson.json')">
<div id="id01"></div>
</body>
</html>
i solved it with
this code
var array =$.parseJSON(JSON.stringify(jsonString));
for (var i = 0; i < array.length; i++) {
var keys =array[i].tags;
var tags = Object.keys(keys);
for(var j = 0 ; j<tags.length; j++){
var obj = {text : tags[j], weight : keys[tags[j]] , link : array[i].url};
Jarray.push(obj);
}
}
The data is provided by an API, so the tag Event : 6 might be the next time Tomorrlowland : 3 the name of event and the weight are given by the API. That's why i can't use jsonString[0].tags.Event because the name event will be different every time.
Thanks all for helping me !

How to dynamically generate javascript objects within other objects. Can you use a for loop inside an object?

I hope to achieve a set of javascript objects something like this:
tabs[0]={
sections[0]={
title:"section0",
children[0]={
title:"Child0"
},
children[1]={
title:"Child1"
},
children[2]={
title:"Child2"
}
},
sections[1]={
title:"section1",
children[0]={
title:"Child0"
},
children[1]={
title:"Child1"
}
}
};
tabs[1]={
sections[0]={
title:"section0",
children[0]={
title:"Child0"
},
children[1]={
title:"Child1"
}
},
sections[1]={
title:"section1",
children[0]={
title:"Child0"
},
children[1]={
title:"Child1"
}
},
sections[2]={
title:"section2",
children[0]={
title:"Child0"
},
children[1]={
title:"Child1"
}
}
};
Here is my code but I'm getting an "Unexpected Token" error at the first for loop within the tab object. Is this not allowed? How could I read these arrays and create objects like those above dynamically? The arrays (and subsequently the objects) can and will change as the .csv files change, which is why I need to dynamically create these objects. These objects will be used in with AngularJS's ng-repeat to create the tabbed and side navigation for an app.
this.tabData = tabsService.tabData;
var tabCount = tabsService.tabData.length;
var tabs={};
var tCounter = 0;
for (tCounter; tCounter<tabCount; tCounter++){
var tabURL = "Contents/Product Groups/"+this.tabData[tCounter]+"/sectionOrder.csv";
tabs[tCounter] ={
"TabSectionData" : $.getCsvArray(tabs[tCounter].tabURL), //gets array from csv file
"sectionCount" : TabSectionData.length
for (sCounter = 0; sCounter<tabs[tCounter].sectionCount; sCounter++){
"tabChildURL" : "Contents/Product Groups/"+this.tabData[tCounter]+"/"+tabs[tCounter].TabSectionData[sCounter]+"/order.csv",
"TabChildData" : $.getCsvArray(tabChildURL) //gets array from csv file
sections[sCounter] ={
"title" = tabs[tCounter].TabSectionData.[sCounter];
cCounter = 0;
for (cCounter = 0; cCounter<TabChildData.length; cCounter++){
children[cCounter]={
"title": tabs[tCounter].TabSectionData[sCounter].TabChildData.[cCounter]
}
}
}
}
}
}
You can run a loop inside a function and instantly execute the function.
I created a Snippet to exemplify.
var obj = {
name: 'My Object',
sections: (function () {
var result = [];
for (var i = 0; i < 10; i++) {
var it = {};
result[i] = it;
it.title = 'Hello';
it.children = [];
for (var j = 0; j < i; j++) {
it.children[j] = 'children' + j;
}
}
return result;
})()
};
var json = JSON.stringify(obj, null, 4);
jQuery('pre').append(json);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>
Regarding your question, 'Can you use for loop inside an object [literal] ', perhaps to create a list of properties, you may do something like this:
Enclose your for loop inside an immediately invoked function. From that function return the result of the loop.
For example:
I want to dynamically add an array of properties using for loop.
var items = {
list : (function(){ // immediately invoked function
var arr = []; // array
for (var i = 0; i < 4; i++)
{
arr.push('item no. '+i); // add each item to array
}
return arr; // return the array as value of the list property
})()
}
RESULT:
items = {
list : [
"item no. 0",
"item no. 1",
"item no. 2",
"item no. 3"
]
}

getJSON returning undefined

I'm trying to make an automatic news feed on a project website, where all the posts are put into a JSON file and then formatted on the news page accordingly. I've finally figured out how to get the json parser to show SOMETHING but that something is just a bunch of "undefined" bits all over the page. What am I doing wrong?
The jquery/html snippet
<script>
$.getJSON("js/news.json", function (data) {
$.each(data.posts, function (val) {
var title = val.title;
var date = val.date;
var content = val.content;
$("#newscontainer").append('<div><h1>' + title + '</h1><h2>' + date + '</h2><p>' + content + '</p></div>');
});
});
</script>
<div id='newscontainer'>
</div>
The JSON snippet
{
"posts": [
{
"title": "title1",
"date": "8302014",
"content": "LotsoftextLotsoftext"
},
{
"title": "title2",
"date": "8312014",
"content": "CopiousquantitiesoftextCopiousquantitiesoftext"
},
{
"title": "title3",
"date": "8322014",
"content": "onlyalittletext"
}
]
}
val in your code is the index, you should use the second argument of the callback.
$.each(data.posts, function (index, val) {
You can also use the this keyword.
Try this one :
var post_title = val.title;
var post_date = val.date;
var post_content = val.content;
var divTag = document.createElement("div");
newscontainer.appendChild(divTag);
var h1Tag = document.createElement("h1");
h1Tag.innerHTML = post_title;
newscontainer.appendChild(h1);
var h2Tag = document.createElement("h2");
h2Tag.innerHTML = post_date;
newscontainer.appendChild(h2);
var pTag = document.createElement("p");
pTag.innerHTML = post_content;
newscontainer.appendChild(p);
You can use the each() function on your list:
$(data.posts).each(function() {
var $this = this;
$("#newscontainer").append('<div><h1>' + $this.title + '</h1><h2>' + $this.date + '</h2><p>' + $this.content + '</p></div>');
});

Categories