How to iterate JSON Array in Jquery - javascript

I have this below type of array. I want to iterate this array in JavaScript. How is this possible?
{
"result": true,
"data": [
{
"ID": 1,
"stage_ID": 1,
"badge_type_ID": 1,
"name": "Despertar da Força",
"description": "Fazer a primeira SuperAtividade",
"type": "",
"image_static": "url123.jpg",
"image_animated": "",
"SQL": "",
"published": 1
},
{
"ID": 2,
"stage_ID": 1,
"badge_type_ID": 1,
"name": "Super 3",
"description": "Fazer 3 SuperAtividades",
"type": "",
"image_static": "urlimage123.png",
"image_animated": "",
"SQL": "",
"published": 1
}
etc
I tried the following script and it is returning "undefined", "undefined".
$.getJSON('https://www.legiaodossuperpoderes.com.br/chronus/api/adm/badges', function(data) {
var output= "<ol>";
for (var i in data) {
output += "<li>" + data[i].ID + "</li>"
}
output+="</ol>";
document.getElementById("placeholder").innerHTML=output;
});
Any solutions ? Thanks!

You can try converting to Json Object
$.getJSON('https://www.legiaodossuperpoderes.com.br/chronus/api/adm/badges', function(data) {
var output= "<ol>";
var jsondata = $.JSON.parse(data); // Json object Convertion
for (var i in data) {
output += "<li>" + data[i].ID + "</li>"
}
output+="</ol>";
document.getElementById("placeholder").innerHTML=output;
});

You are trying to access an undefined property using data[i].ID .
When you are getting response from your getJSON() function then you need to call the response with a name and then you can access any inner property using this name .
Now if you want to iterate using data key/value on myResponse variable then you need to do this.
$.getJSON('https://www.legiaodossuperpoderes.com.br/chronus/api/adm/badges', function(myResponse) {
var output= "<ol>";
var dataCount = myResponse.data.length;
for (var i = 0; i < dataCount; i++) {
output += "<li>" + myResponse.data[i].ID + "</li>";
}
output+="</ol>";
document.getElementById("placeholder").innerHTML=output;
});

Related

JSON is returning [object Object] and then result instead of only the result

So I will explain quickly. I am really new to JSON and Jquery/Javascript. I am building an internal website for a school and I want to build a specific page for each grade with the students listed on the page. Then all students has his personal page. The Json file looks like this:
[
{
"id": "sixthgrade",
"grade": "Sixth grade",
"URL": "/grades/sixthgrade.html",
"listStudents": [
{
"studentName": "John Doe",
"stuudentId": "johndoe",
"studentPage": "/students/johndoe.html",
"studentImageUrl": "/images/students/johndoe.jpg"
}
]
},
{
"id": "sixthgrade",
"grade": "Sixth grade",
"URL": "/grades/sixthgrade.html",
"listStudents": [
{
"StudentName": "Paul Jackson",
"studentId": "pauljackson",
"studentPage": "/students/pauljackson.html",
"studentImageUrl": "/images/students/pauljackson.jpg"
},
{
"StudentName": "Alisson Smith",
"studentId": "sixthgrade",
"studentPage": "/students/alissonsmith.html",
"studentImageUrl": "/images/students/alissonsmith.jpg"
}
]
}
]
And the JavaScript is that:
$.getJSON("/scripts/school.json", function(data) {
var table = [];
var studentId = '';
var studentName = '';
var studentImageUrl = '';
var studentPage = '';
var gradeId = '';
$.each(data, function(key, val) {
table = val['listStudents'];
gradeId = val['id'];
$.each(table, function(id, value) {
studentId = value['studentId'];
studentName = value['studentName'];
studentImageUrl = value['studentImageUrl'];
studentPage = value['studentPage'];
table.push("<li class='container-image " + studentId + "'><a href='" + studentPage + "'><img src='" + studentImageUrl + "' /><span class='text'>" + studentName + "</span></a></li>");
console.log(table);
});
$("<ul/>", {
"class": "students-list " + gradeId + "",
html: table.join('')
}).appendTo("#list-students");
});
});
I get this result for the 1st row UL [object Object] then the result of the Li that is what I only want to have.
For the 2nd row, I have UL [object Object][object Object] then the 2 LI with the only results I want to have.
For each row I have [object Object] depending of the number of students and then the LI with the information I want to have.
I tried to put JSON.stringify() everywhere I could and still getting [object Object].
Help would be so helpful. Thanks in advance.
You have an array table which is equal to val['listStudents'] and contains data.
Later on, you additionally push HTML into that array.
I would suggest you use a separate variable for your HTML output.
table = val['listStudents'];
let output = [];
gradeId = val['id'];
$.each(table, function (id, value) {
studentId = value['studentId'];
studentName = value['studentName'];
studentImageUrl = value['studentImageUrl'];
studentPage = value['studentPage'];
output.push("<li class='container-image " + studentId + "'><a href='" + studentPage + "'><img src='" + studentImageUrl + "' /><span class='text'>" + studentName + "</span></a></li>");
console.log(output);
});
$( "<ul/>", {
"class": "students-list " + gradeId + "",
html: output.join('')
}).appendTo("#list-students");
Check your JSON - studentName VS StudentName and in Javascript avoid to using same variable for processing and input table - here is working code & JSON:
[
{
"id": "sixthgrade",
"grade": "Sixth grade",
"URL": "/grades/sixthgrade.html",
"listStudents": [
{
"studentName": "John Doe",
"stuudentId": "johndoe",
"studentPage": "/students/johndoe.html",
"studentImageUrl": "/images/students/johndoe.jpg"
}
]
},
{
"id": "sixthgrade",
"grade": "Sixth grade",
"URL": "/grades/sixthgrade.html",
"listStudents": [
{
"studentName": "Paul Jackson",
"studentId": "pauljackson",
"studentPage": "/students/pauljackson.html",
"studentImageUrl": "/images/students/pauljackson.jpg"
},
{
"studentName": "Alisson Smith",
"studentId": "sixthgrade",
"studentPage": "/students/alissonsmith.html",
"studentImageUrl": "/images/students/alissonsmith.jpg"
}
]
}
]
Javascript:
$.getJSON( "students.json", function( data ) {
$.each(data, function (key, val) {
var outputHTML = [];
var table = val['listStudents'];
var gradeId = val['id'];
$.each(table, function (id, value) {
var studentId = value['studentId'];
var studentName = value['studentName'];
var studentImageUrl = value['studentImageUrl'];
var studentPage = value['studentPage'];
outputHTML.push("<li class='container-image " + studentId + "'><a href='" + studentPage + "'><img src='" + studentImageUrl + "' /><span class='text'>" + studentName + "</span></a></li>");
console.log(outputHTML);
});
$( "<ul/>", {
"class": "students-list " + gradeId + "",
html: outputHTML.join('')
}).appendTo("#list-students");
});
});
[object Object] usually happens when JSON is accidentally converted to string somewhere along the process, often seen in the real world in LocalStorage.
To fix your problem, try JSON.parse() instead
In addition, consider exporting your data from a JS file as a complex constant object to import into another file where you might need it. You can avoid a lot of JSON errors and additional parsing discrepancies. JSON is most typically used in an API response, but not really for anything else. Most javascript developers would agree that staying within the scope of javascript with code is better due to being able to actually test said code, instead of having to import a file of another type. See more here.

JSON add value on click

I'm trying to make a site of restaurant and now doing some table reservation. So far have one problem:
I have a JSON of tables and want to add date (day/time) to it, when table was clicked.
The problem's next - when I click on some table, the date adds to all JSON elements. And I wand to add it only to the element I clicked.
Here is link to codepen:
https://codepen.io/wilchilly/pen/qBEvegW
(To see the result click on some table and open console)
My HTML:
<p class="href-to italic" id="showMore">Show tables</p>
<div class="wrapper" id="wrapper">
<div class="tables-wrapper" id="tables-wrapper"></div>
</div>
JS:
fetch('tables.json')
.then(response => response.json())
.then(json => {
const myJson = json;
let showTables = document.getElementById('showMore');
//show elements on page
function loadGoods(data) {
let out = '';
for (let key in data) {
if (data[key].isAvailable == false) {
out += '<div class="single-table not-available" data-name="' + data[key]['name'] + '" data-art="' + data[key]['id'] + '">';
out += '<h4>' + data[key]['name'] + '</h4>';
out += '<p>' + data[key]['location'] + '</p>';
out += '</div>';
} else {
out += '<div class="single-table" data-name="' + data[key]['name'] + '" data-art="' + data[key]['id'] + '">';
out += '<h4>' + data[key]['name'] + '</h4>';
out += '<p>' + data[key]['location'] + '</p>';
out += '</div>';
}
}
$('#tables-wrapper').html(out);
}
//set Date (day/time)
function setDate() {
for (let key in myJson) {
myJson[key]['date']['day'] = '10/02';
myJson[key]['date']['time'] = '20:00';
}
console.log(myJson);
}
showTables.addEventListener('click', function () {
loadGoods(myJson);
let singleTable = document.getElementsByClassName('single-table');
Array.from(singleTable).forEach(function (element) {
element.addEventListener('click', setDate);
});
});
})
JSON:
[
{
"id": 0,
"index": 0,
"name": "Table 1",
"capacity": 5,
"isAvailable": true,
"location": "Bar",
"date": {
"day": " ",
"time": ""
}
},
{
"id": 1,
"index": 1,
"name": "Table 2",
"capacity": 5,
"isAvailable": true,
"location": "Patio",
"date": {
"day": " ",
"time": " "
}
},
{
"id": 2,
"index": 2,
"name": "Table 3",
"capacity": 5,
"isAvailable": true,
"location": "Bar",
"date": {
"day": " ",
"time": " "
}
},
{
"id": 3,
"name": "Table 4",
"capacity": 6,
"isAvailable": true,
"location": "Inside",
"date": {
"day": " ",
"time": " "
}
}
]
I found a solution. This might be helpful for someone with a similar question.
function setDate() {
let inputDay = document.getElementById('form-data').value;
let inputTime = document.getElementById('form-time').value;
for (let i = 0; i < myJson.length; i++) {
if (this.getAttribute('data-art') == myJson[i].id) {
myJson[i]['date']['day'] = inputDay;
myJson[i]['date']['time'] = inputTime;
}
}
}
Just use the index from the iteration on table creation as id (or any attr you like) for example (you will probably need a classic for or a foreach) and then, in the event you attached pass the click event as param. Finally you just use the event.target to get the id (or the attr you choose) of the element and use it in the setDate func.

I need to loop this array

I use ajax to get a array from Economic and i would like to loop though it. The array (sortned):
{
"collection": [
{ "customerNumber": 1, "email": "jo+billing#test.com", "name": "Tester Test" }
, { "customerNumber": 2, "name": "Demo Name" }
]
, "metaData": { "more array" }
, "pagination": { "more array"}
, "self": "some url"
}
The jquery I think I need to use but give me a error: (TypeError: cannot use 'in' operator to search for 'length' in '{
"collectio...')
$.ajax({}).always(function (data) {
var options = $('#example').attr('options');
var substr = JSON.stringify(data, null, 4);
//-----------loop part------------
$.each((substr), function(i, val1) {
$.each(val1.customerNumber, function(a, val3) {
var CustInfo = val1[a]["name"] + " " + val1[a]["email"];
options[options.length] = new Option(CustInfo, val1[a]["customerNumber"]);
});
});
});
I am only interested in the values in "collection" and I want a select box with the customers info in it. like this:
<select>
<option value="1">Tester Test jo+billing#test.com</option>
<option value="2">Demo Name</option>
</select>
First, you don't have to use JSON.stringify() that will convert your response object data to a string that you can't loop through the attributes.
I am only interested in the values in "collection".
Then no need for two loops just use the data.collection :
$.ajax({}).always(function (data) {
var options = $('#example').attr('options');
$.each((data.collection), function(i, obj) {
var CustInfo = obj["name"] + " " + obj["email"];
options[options.length] = new Option(CustInfo, obj["customerNumber"]);
});
});
data = {
"collection": [{
"customerNumber": 1,
"email": "jo+billing#test.com",
"name": "Tester Test"
}, {
"customerNumber": 2,
"name": "Demo Name"
}],
"metaData": [],
"pagination": [],
"self": "some url"
};
$.each((data.collection), function(i, val1) {
var CustInfo = val1["name"] + " " + val1["email"];
console.log(CustInfo, val1["customerNumber"]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to parse nested JSON in Javascript?

I am trying to parse and show JSON data (product catalog) using XMLHttpRequest method. I am able to display the brands and their names, but not able to showcase list of products progmatically.
Here is the sample JSON request:
{
"products": {
"laptop": [{
"brand": "sony",
"price": "$1000"
}, {
"brand": "acer",
"price": "$400"
}],
"cellphone": [{
"brand": "iphone",
"price": "$800"
}, {
"brand": "htc",
"price": "$500"
}],
"tablets": [{
"brand": "iPad",
"price": "$800"
}, {
"brand": "htc-tab",
"price": "$500"
}]
}
}
Right now I am using following code to show data in tabluar form:
function loadJSON() {
var data_file = "http://localhost/AJAX/productcatalog.json";
var http_request = new XMLHttpRequest();
http_request.onreadystatechange = function () {
if ((http_request.readyState == 4) && (http_request.status == 200)) {
// Javascript function JSON.parse to parse JSON data
var jsonObj = JSON.parse(http_request.responseText);
data = '<table border="2"><tr><td>Type</td><td>Brand</td><td>Price</td></tr>';
var i = 0;
debugger;
for (i = 0; i < jsonObj["products"].laptop.length; i++)
{
obj = jsonObj["products"].laptop[i];
data = data + '<tr><td>laptop</td><td>' + obj.brand + '</td><td>' + obj.price + '</td></tr>';
}
for (i = 0; i < jsonObj["products"].cellphone.length; i++)
{
obj = jsonObj["products"].cellphone[i];
data = data + '<tr><td>laptop</td><td>' + obj.brand + '</td><td>' + obj.price + '</td></tr>';
}
for (i = 0; i < jsonObj["products"].tablets.length; i++)
{
obj = jsonObj["products"].tablets[i];
data = data + '<tr><td>laptop</td><td>' + obj.brand + '</td><td>' + obj.price + '</td></tr>';
}
data += '</table>';
document.getElementById("demo").innerHTML = data;
}
}
http_request.open("GET", data_file, true);
http_request.send();
}
Question What is the way to fetch product list , i.e. products, cellphone and tablets ? Right now I have hardcoded that in order to fetch complete list of brands. Please advice. (I want to use plain javascript and not jquery)
Thanks!
It sounds like what you're missing is the "How do I iterate over an object when I don't know all the keys".
An object is a set of key, value pairs. You can use for/in syntax: for( var <key> in <object> ){} to get each key.
For your use case it might be something like:
var products = jsonObject['products'];
for( var productName in products ){
//productName would be "laptop", "cellphone", etc.
//products[productName] would be an array of brand/price objects
var product = products[productName];
for( var i=0; i<product.length; i++ ){
//product[i].brand
//product[i].price
}
}
In practice, I might use something a little less verbose, but this makes it easier to understand what is going on.
To achieve the expected i have used for loop and HTML DOM createElement() Method
var product_catalog = {
"products": {
"laptop": [{
"brand": "sony",
"price": "$1000"
}, {
"brand": "acer",
"price": "$400"
}],
"cellphone": [{
"brand": "iphone",
"price": "$800"
}, {
"brand": "htc",
"price": "$500"
}],
"tablets": [{
"brand": "iPad",
"price": "$800"
}, {
"brand": "htc-tab",
"price": "$500"
}]
}
};
var output = document.querySelector('#product tbody');
function build(JSONObject) {
/**get all keys***/
var keys = Object.keys(JSONObject);
/**get all subkeys***/
var subkeys = Object.keys(JSONObject[keys]);
console.log(subkeys);
/**loop sub keys to build HTML***/
for (var i = 0, tr, td; i < subkeys.length; i++) {
tr = document.createElement('tr');
td = document.createElement('td');
td.appendChild(document.createTextNode(subkeys[i]));
tr.appendChild(td);
output.appendChild(tr);
}
};
build(product_catalog);
HTML:
Coepen URL for reference- http://codepen.io/nagasai/pen/xOOqMv
Hope this works for you :)
Look at this example:
var x = data.key1.children.key4;
var path = "data";
function search(path, obj, target) {
for (var k in obj) {
if (obj.hasOwnProperty(k))
if (obj[k] === target)
return path + "['" + k + "']"
else if (typeof obj[k] === "object") {
var result = search(path + "['" + k + "']", obj[k], target);
if (result)
return result;
}
}
return false;
}
//Then for evry node that you need you can call the search() function.
var path = search(path, data, x);
console.log(path); //data['key1']['children']['key4']
I think this is what you're asking about, you can use Object.keys to get the properties of an object, then loop through them afterward.
var data = {
"products": {
"laptop": [{
"brand": "sony",
"price": "$1000"
}, {
"brand": "acer",
"price": "$400"
}],
"cellphone": [{
"brand": "iphone",
"price": "$800"
}, {
"brand": "htc",
"price": "$500"
}],
"tablets": [{
"brand": "iPad",
"price": "$800"
}, {
"brand": "htc-tab",
"price": "$500"
}]
}
}
var typesOfProducts = Object.keys(data.products)
console.log(typesOfProducts)
document.getElementById('output').textContent = typesOfProducts.toString()
//Then, to loop through
var i = -1,
len = typesOfProducts.length
function handleProduct(productType) {
console.log("This is the " + productType + " data.")
console.log(data.products[productType])
}
while (++i < len) {
handleProduct(typesOfProducts[i])
}
<div id="output"></div>
It sounds like what you're looking for is just an array of the keys of the "products" object. Example:
Products: ["laptop", "cellphone", "tablets"];
If so, I would just run your json object through javascript's Object.keys() method.
var jsonObj = JSON.parse(http_request.responseText);
var products = Object.keys(jsonObj.products);
// products = ["laptop", "cellphone", "tablets"];

Array data wont display in a table

I have an ajax function which sends a get request to an api and returns data in the following format-
{
"firstname": "John",
"lastname": "Doe",
"email": "doej#gmail.com",
"subjects": [
{
"id": 1,
"name": "maths"
},
{
"id": 2,
"name": "chemistry"
}
]
},
I need to display this data in a table but am having trouble getting the subjects array to display correctly, ie as a list in one table cell. I have tried to put the array data into another table inside the main one but it's not working out. I presume I'm going very wrong somewhere in my iteration loops.
function getPeople() {
$.ajax({
type: "GET",
url: "http://example.com",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "json",
success: function (data, status, jqXHR) {
// fill a table with the JSON
$("table.mytable").html("<tr><th></th><th>First Name</th><th>Last Name</th><th>Subjects</th></tr>" );
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].subjects.length; j++) {
var subjects = data[i].subjects[j];
$("table.insidetable").append('<tr><td>' + subjects + 'tr><td>')
}
$("table.mytable").append('<tr><td><input type = "checkbox" id = '+data[i].id+'>' + "</td><td>" + data[i].firstname + "</td><td>" + data[i].lastname + "</td><td>" + "table.insidetable" + "</td></tr>");
}
},
error: function (jqXHR, status) {
// error handler
console.log(jqXHR);
alert('fail' + status.code);
}
});
}
Below is the working (tested) code.
var data = [{
"firstname": "John",
"lastname": "Doe",
"email": "doej#gmail.com",
"subjects": [
{
"id": 1,
"name": "maths"
},
{
"id": 2,
"name": "chemistry"
}
]
},
{
"firstname": "Steve",
"lastname": "Gentile",
"email": "steve#gmail.com",
"subjects": [
{
"id": 1,
"name": "history"
},
{
"id": 2,
"name": "geography"
}
]
}];
$("table.mytable").html("<tr><th></th><th>First Name</th><th>Last Name</th><th>Subjects</th></tr>");
for (var i = 0; i < data.length; i++) {
var subjectList = '';
for (var j = 0; j < data[i].subjects.length; j++) {
subjectList += '<li>' + data[i].subjects[j].name + '</li>';
}
$("table.mytable").append('<tr><td><input type="checkbox" id=' + i +'/></td><td>' + data[i].firstname + '</td><td>' + data[i].lastname + '</td><td><ul>' + subjectList + '</ul></td></tr>');
}
It seems there are many problems in below statement like,
Tags are not closed properly
Properties that do not exist are being used (data[i].id)
Single and Double quotes don't match
...
$("table.mytable").append('<tr><td><input type = "checkbox" id = '+data[i].id+'>' + "</td><td>" +data[i].firstname + "</td><td>" + data[i].lastname + "</td><td>" + "table.insidetable"+ "</td></tr>");
As a guess are you missing a '<'?
In the line:
$("table.insidetable").append('<tr><td>' + subjects + 'tr><td>')
Also
$("table.mytable").append('<tr><td><input type = "checkbox" id = '+data[i].id+'>' + "</td><td>" + data[i].firstname + "</td><td>" + data[i].lastname + "</td><td>" + "table.insidetable" + "</td></tr>");
I don't think you should be appending "table.insidetable"? This will be seen rendered as the value "table.insidetable" and not the contents of the table. I think this should rather be something like $("table.insidetable").val()

Categories