{"menu" :[{
"name": "Computers",
"children": [{
"name": "Notebook",
"children": [{
"name": "Apple"
}, {
"name": "Windows"
}]
}, {
"name": "Tablets",
"children": [{
"name": "Apple"
}, {
"name": "Android"
}, {
"name": "Windows"
}]
}]
}, {
"name": "Phones",
"children": [{
"name": "Android",
"children": [{
"name": "Samsung"
}, {
"name": "Nokia"
}, {
"name": "Lenovo"
}]
}, {
"name": "Windows Phones",
"children": [{
"name": "Microsoft"
}, {
"name": "Nokia"
}]
}]
}, {
"name": "Cameras",
"children": [{
"name": "Digital",
"children": [{
"name": "Nikon"
}, {
"name": "Fuji"
}]
}, {
"name": "DSLR",
"children": [{
"name": "Canon"
}, {
"name": "Nikon"
}]
}]
}]
}
and i want to print it so each parent have its children .. here is my code
$(document).ready(function() {
$.ajax({
url: 'menuData.json',
type: 'get',
dataType: 'json',
error: function(data){
alert("error");
},
success: function(data){
var i=0;
var j=0;
var n=0;
var obj=data;
var json = JSON.stringify(obj);
var s = JSON.parse(json);
for( i=0;i<s.menu.length;i++){
$("#main-menu").append(' <li>'+ s.menu[i].name +'</li>');
for( j=0;j<s.menu[i].children.length;j++)
{ $("#main-menu").append(' <li>'+ s.menu[i].children[j].name + '</li>');
for( n=0;n<s.menu[i].children[j].children.length;n++){
$("#main-menu").append(' <li>'+ s.menu[i].children[j].children[n].name +'</li>');
}
}
}
$('#main-menu').smartmenus({
subMenusSubOffsetX:1,
subMenusSubOffsetY: -8
});
}
});
});
but it ends up like this
any help please .. thanks in advance .. btw i am beginner so please help me .. thanks again
Your code is logically correct except you are always appending to the $("#main-menu"). Consider doing this:
...
for( var i=0; i < s.menu.length; i++)
{
$("#main-menu").append(' <li id="menu-list-' + i + '">' + s.menu[i].name + '</li>');
var list_length = s.menu[i].children.length;
if (list_length > 0)
$("#main-menu li#menu-list-" + i).append('<ul></ul>');
for( var j=0; j < list_length; j++)
{
$("#main-menu li#menu-list-" + i + " ul").append(' <li id="menu-list-' + i + '-children-list-' + j + '">'+ s.menu[i].children[j].name + '</li>');
var children_list_length = s.menu[i].children[j].children.length;
if(children_list_length > 0)
$("#main-menu li#menu-list-" + i + " ul li#menu-list-" + i + "-children-list-" + j).append("<ul></ul>");
for( var n=0; n < children_list_length; n++)
{
$("#main-menu li#menu-list-" + i + " ul li#menu-list-" + i + "-children-list-" + j + " ul").append(' <li>'+ s.menu[i].children[j].children[n].name +'</li>');
}
}
}
...
Related
I have a json data and i want to display it in dl tags and i want to create new dl tags every time i loop through the json data, but the output i got is the dl will be created and closed before the dt and dd which were suppose to be inide it is created, you can see in the fiddle below jsfiddle.net/buo28k1L/56/. Below is my code i added style to the dl to show where the dl is formed and you can see that the dt and dd are outside of the dl instead of being inside it.
HTML
<div id="content"></div>
CSS
dl {
border:1px solid red;
height: 100px;
width: 300px;
}
JS
var data = [
[{
"id": "67",
"name": "Baby & Toddler Clothing "
}, {
"id": "68",
"name": "Kids' Clothing, Shoes & Accessories"
}, {
"id": "69",
"name": "Costumes, Reenactment Theater"
}],
[
[{
"id": "572",
"name": "Baby Clothing Accessories "
}, {
"id": "573",
"name": "Baby Shoes"
}],
[{
"id": "579",
"name": "Boys Clothing [Sizes 4 & Up] "
}, {
"id": "580",
"name": "Boys Shoes"
}],
[{
"id": "588",
"name": "Costumes"
}, {
"id": "589",
"name": "Reenactment & Theater "
}]
]
]
if (data.length > 0) {
var content = $("#content");
firstdata = data[0];
secdata = data[1];
for (var i = 0; i < firstdata.length; i++) {
// var d = $( document.createElement('dl') );
var dl = $("#content").append("<dl/>");
dl.append("<dt href='" + firstdata[i].id + "'>" + firstdata[i].name + "</dd>");
for (var j = 0; j < secdata.length; j++) {
if (secdata[i][j] !== undefined) {
dl.append("<dd href='" + secdata[i][j].id + "'>" + secdata[i][j].name + "</dd>");
}
}
}
content.append(dl);
} else {
console.log('no item for this categories');
}
There is a mistake inside your first for loop.
try this one.
for (var i = 0; i < firstdata.length; i++) {
// var d = $( document.createElement('dl') );
//create an empty dl tag
var dl = $("<dl></dl>");
//append your dt
dl.append("<dt href='" + firstdata[i].id + "'>" + firstdata[i].name + "</dt>");
//append your all dd
for (var j = 0; j < secdata.length; j++) {
if (secdata[i][j] !== undefined) {
dl.append("<dd href='" + secdata[i][j].id + "'>" +secdata[i][j].name + "</dd>");
}
}
//append each dl before starting new one.
content.append(dl);
}
You are using append() incorrectly. What you can do is first create a HTML string with dt and dd so that this can be then added to dl and then append this dl to div with id as content. For further verification of below snippet, you can use browser inspect element and you will see that the HTML is rendered as
<dl>
<dt href="67">Baby & Toddler Clothing </dt>
<dd href="572">Baby Clothing Accessories </dd>
<dd href="573">Baby Shoes</dd>
</dl>
var data = [
[{
"id": "67",
"name": "Baby & Toddler Clothing "
}, {
"id": "68",
"name": "Kids' Clothing, Shoes & Accessories"
}, {
"id": "69",
"name": "Costumes, Reenactment Theater"
}],
[
[{
"id": "572",
"name": "Baby Clothing Accessories "
}, {
"id": "573",
"name": "Baby Shoes"
}],
[{
"id": "579",
"name": "Boys Clothing [Sizes 4 & Up] "
}, {
"id": "580",
"name": "Boys Shoes"
}],
[{
"id": "588",
"name": "Costumes"
}, {
"id": "589",
"name": "Reenactment & Theater "
}]
]
]
if (data.length > 0) {
var content = $("#content");
firstdata = data[0];
secdata = data[1];
for (var i = 0; i < firstdata.length; i++) {
// var d = $( document.createElement('dl') );
var dtHTML = "<dt href='" + firstdata[i].id + "'>" + firstdata[i].name + "</dt>";
for (var j = 0; j < secdata.length; j++) {
if (secdata[i][j] !== undefined) {
dtHTML += "<dd href='" + secdata[i][j].id + "'>" + secdata[i][j].name + "</dd>";
}
}
$("#content").append('<dl>'+dtHTML+'</dl>');
}
} else {
console.log('no item for this categories');
}
dl{
border:1px solid red;
height: 100px;
width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content"></div>
You can also do it with Javascript
if(data.length > 0) {
var content = document.getElementById('content');
firstdata = data[0];
secdata = data[1];
var dl = document.createElement('dl');
for (var i = 0; i < firstdata.length; i++) {
var dt = document.createElement('dt');
dt.href = firstdata[i].id;
dt.append(document.createTextNode(firstdata[i].name));
dl.append(dt);
for (var j = 0; j < secdata.length; j++) {
if (secdata[i][j] !== undefined) {
var dd = document.createElement('dd');
dd.href = secdata[i][j].id;
dd.append(document.createTextNode(secdata[i][j].name));
dl.append(dd);
}
}
}
content.append(dl);
}
else
{
console.log('no item for this categories');
}
You can solve your problem in a much simpler way by using the template string (``) backticks.
Create your html structure using these backticks(``) and just append the content to the div
var data = [
[{
"id": "67",
"name": "Baby & Toddler Clothing "
}, {
"id": "68",
"name": "Kids' Clothing, Shoes & Accessories"
}, {
"id": "69",
"name": "Costumes, Reenactment Theater"
}],
[
[{
"id": "572",
"name": "Baby Clothing Accessories "
}, {
"id": "573",
"name": "Baby Shoes"
}],
[{
"id": "579",
"name": "Boys Clothing [Sizes 4 & Up] "
}, {
"id": "580",
"name": "Boys Shoes"
}],
[{
"id": "588",
"name": "Costumes"
}, {
"id": "589",
"name": "Reenactment & Theater "
}]
]
]
if (data.length > 0) {
var content = $("#content");
var dlList = data[0].map((dt, index) => {
var ddList = data[1][index].map(dd => {
return `<dd>${dd.name}</dd>`;
}).join('');
return `<dl>
<dt>${dt.name}</dt>
${ddList}
</dl>`;
}).join('');
content.append(dlList);
} else {
console.log('no item for this categories');
}
dl{
border:1px solid red;
height: 100px;
width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content"></div>
I'm trying to generate HTML table from JSON
The JSON provided is deeply nested. With the help of this thread How do I loop through deeply nested properties of a JavaScript object?, I am able to get the values of the JSON but I am confused on how to generate the HTML table
var districts = {
"district": [{
"ration": 4,
"states": [{
"name": "Louisiana",
"population": 42383,
"cities": [{
"name": "Cavalero"
}]
}]
}, {
"ration": 1,
"states": [{
"name": "Colorado",
"population": 980,
"cities": []
}, {
"name": "Arkansas",
"population": 58998,
"cities": []
}, {
"name": "Illinois",
"population": 59333,
"cities": [{
"name": "Kenwood"
}]
}]
}, {
"ration": 2,
"states": [{
"name": "Washington",
"population": 83984,
"cities": [{
"name": "Conestoga"
}, {
"name": "Whitehaven"
}, {
"name": "Dellview"
}]
}, {
"name": "West Virginia",
"population": 38034,
"cities": []
}]
}]
};
var i, district, j, states, k, cities;
for (i = 0; i < districts.district.length; i++) {
district = districts.district[i];
print(i + 1, ". District", i + 1, "consists of following states", "--- ration", district.ration);
for (j = 0; j < district.states.length; j++) {
states = district.states[j];
var said = (states.cities.length > 0) ? ("consists of following cities") : ("");
print(i + 1, ".", j + 1, states.name, said, "--- population", states.population);
for (k = 0; k < states.cities.length; k++) {
cities = states.cities[k];
print(" ", i + 1, ".", j + 1, ".", k + 1, cities.name);
}
}
}
Run this on Ideone
Any pointers/help/suggestions appreciated
You will need to generate a table, like this:
var districts = {
"district": [{
"ration": 4,
"states": [{
"name": "Louisiana",
"population": 42383,
"cities": [{
"name": "Cavalero"
}]
}]
}, {
"ration": 1,
"states": [{
"name": "Colorado",
"population": 980,
"cities": []
}, {
"name": "Arkansas",
"population": 58998,
"cities": []
}, {
"name": "Illinois",
"population": 59333,
"cities": [{
"name": "Kenwood"
}]
}]
}, {
"ration": 2,
"states": [{
"name": "Washington",
"population": 83984,
"cities": [{
"name": "Conestoga"
}, {
"name": "Whitehaven"
}, {
"name": "Dellview"
}]
}, {
"name": "West Virginia",
"population": 38034,
"cities": []
}]
}]
};
//Start of the table, including header
var table = '<table><thead><tr><th>Num</th><th>District</th><th>Population</th><th>Ration</th></tr></thead><tbody>';
//Num
for (var i = 0; i < districts.district.length; i++) {
//District
var district = districts.district[i];
//First row
table += '<tr><td>' + (i + 1) + '</td><td>District ' + district.ration + ' consists of the following states:</td><td></td><td>' + district.ration + '</td></tr>';
//States
var states = district.states;
for (var j = 0; j < states.length; j++) {
table += '<tr><td></td><td>' + (i + 1) + '.' + (j + 1) + ' ' + states[j] + ((states[j].cities && states[j].cities.length) ? ' consists of following cities:' : '') + '</td><td>' + states[j].population + '</td><td></td></tr>';
//Cities
if (states[j].cities) {
for (var k = 0; k < states[j].cities; k++) {
table += '<tr><td></td><td>' + (i + 1) + '.' + (j + 1) + '.' + (k + 1) + ' ' + states[j].cities[k].name + '</td><td></td><td></td></tr>';
}
}
}
}
//End of the table
table += '</tbody></table>';
and then add table somewhere into your html.
if you want to generate the desired output as on that link, you can use
<ol>
<li></li>
<li>
<ol><li></li></ol>
<li>
</ol>
instead of table. generate it using javascript. you can use below code to generate your ordered list which should be inserted on the main ordered list tag.
var district = districts.district;
function generateCities(cities){
cities.map((city) => {
return (
"<li>"+ city.name + "</li>"
)
})
}
function generateStates(states, generateCities){
states.map((stat) => {
return (
"<li>"+stat.name + " consists of following cities --- population " + stat.population + "</li>"
+"<ol>" + generateCities(stat.cities) + "</ol>"
)
});
}
function generateMyHtml(district, generateStates){
district.map((dist, index) => {
return (
"<li> District "+ index + "consists of following states --- ration " + dist.ration + "</li>"
+"<ol>" + generateStates(dist.states) + "</ol>"
)
});
};
hope this is helpful
i have a json and i create a simple dynamic form based on my json file . there are labels and each lables are exist in divs seperately.but there is a problem in this code that this code does not show my inputs. how to appends them inside each divs below each lable?
this code should show input but does not work.
here is my code :
document.body.onload = addElement;
function addElement() {
var schema = [{
"queestion": "Name",
"type": "128",
"attrs": [{
"attr": {
"name": "class",
"value": "nofilling2 engword"
}
},
{
"attr": {
"name": "id",
"value": "name"
}
},
{
"attr": {
"name": "type",
"value": "text"
}
},
{
"attr": {
"name": "placeholder",
"value": "Name"
}
},
{
"attr": {
"name": "name",
"value": "_root.passengerinfo__1.passengerinfo.fullname.firstname"
}
}
]
},
{
"queestion": "Family",
"type": "128",
"attrs": [{
"attr": {
"name": "class",
"value": "nofilling2 engword"
}
},
{
"attr": {
"name": "id",
"value": "family"
}
},
{
"attr": {
"name": "type",
"value": "text"
}
},
{
"attr": {
"name": "placeholder",
"value": "Family"
}
},
{
"attr": {
"name": "name",
"value": "_root.passengerinfo__1.passengerinfo.fullname.lastname"
}
}
]
}
]
for (var i = 0; i < schema.length; i++) {
var type = schema[i].type;
if (type == 128) {
var titleinput = schema[i].queestion;
var newDiv = document.createElement("div");
newDiv.className = 'c-infoo';
var newContent = document.createElement('label');
newContent.className = 'abs-tlt';
newDiv.appendChild(newContent);
newContent.innerHTML = titleinput + " : ";
document.getElementById('tblreserve').appendChild(newDiv);
var string = "<input ";
for (var y = 0; y < schema[i].attrs.length; y++) {
string += schema[i].attrs[y].attr.name + '="' + schema[i].attrs[y].attr.value + '" '
}
string += ">";
newDiv.appendChild = string;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="tblreserve"></div>
In your last line you wrote newDiv.appendChild=string;.
But stringas its name says is a String and can't be appended as an child.
You can use your string by writing newDiv.innerHTML+=string; instead.
PS: Please fix your indentation style. It doesn't look very nice...
I have been trying for a week to turn a HUGE javascript object to an unordered list. the function I have right now doesnt right. it returns only the first layer. the rest it doesnt. freezing of the browser is also a problem which my solution is to use setTimeout(function,0);
JSON format:
{
"name": "",
"value": { //JSON always start with these 2. content is inside this value key.
"randomname": {
"type": "list",
"value": {
"type": "int", //another type and value to that is in the array
"value": [26, 32, 25]
}
},
"randomname": {
"type": "int",
"value": 5
},
"randomname": {
"type": "string",
"value": "string or something"
},
"randomname": {
"type": "compound", //compound types can be inside compound types can be inside compount types etc.
"value": {
"randomname": {
"type": "int",
"value": 6
},
"randomname": {
"type": "int",
"value": 6
}
}
},
"randomname": {
"type": "long",
"value": [0.0345034, 4.345345]
}
}
The code I tried to make:
function readObject(el, data, boo) {
for(var ind in data) {
el.innerHTML += '<li>';
if (boo) {
el.innerHTML += ind + ' - ';
}
console.log("another loop");
switch (data[ind].type) {
case "compound":
el.innerHTML += data[ind].type + ' - ';
setTimeout(function (){ readObject(el,data[ind].value,false); el.innerHTML += '</li>';},0);
break;
case "string":
el.innerHTML += data[ind].type + ' - ';
el.innerHTML += data[ind].value;
callback();
break;
case "int":
el.innerHTML += data[ind].type + ' - ';
el.innerHTML += data[ind].value;
callback();
break;
case "long":
el.innerHTML += data[ind].type + ' - ';
el.innerHTML += data[ind].value[0] + ' - ' + data[ind].value[1];
callback();
break;
case "list":
el.innerHTML += data[ind].type + ' - ';
el.innerHTML += data[ind].value.type + ' - ';
setTimeout(function (){ readObject(el,listToObject(data[ind].value),false);el.innerHTML += '</li>'; },0);
break;
}
function callback() {
el.innerHTML += '</li>';
}
}
}
(All other types will be the same of string)
Manipulating the DOM is slow.
But there is also another issue with your code: you use setTimeout, and in the callbacks you provide to it, you reference a variable ind that will have changed by the time the callback is executed, leading to undesired results if any.
Your code does not produce any ul tags, only li tags. NB: You did not provide the definition of the function listToObject, but I assume it is not problematic (although arrays are objects).
Here is an implementation that will also deal well with cases where you have a list of less trivial sub types, such as "compound" -- I added an example at the end of the sample data:
function objectToHtml(data, defaultType) {
var html = '';
for (var ind in data) {
var item = data[ind],
type = defaultType || item.type,
value = defaultType ? item : item.value;
html +=
'<li>\n' +
(defaultType ? '' : ind + ' - ' + type + ' - ') +
(type === "compound" ? objectToHtml(value)
: type === "list" ? value.type + ' - '
+ objectToHtml(value.value, value.type)
: type === "long" ? value.join(' - ')
: value) +
'</li>\n';
}
return '<ul>\n' + html + '</ul>\n';
}
// Sample data
var data = {
"name": "",
"value": {
"randomname1": {
"type": "list",
"value": {
"type": "int",
"value": [26, 32, 25]
}
},
"randomname2": {
"type": "int",
"value": 5
},
"randomname3": {
"type": "string",
"value": "string or something"
},
"randomname4": {
"type": "compound",
"value": {
"randomname5": {
"type": "int",
"value": 6
},
"randomname6": {
"type": "int",
"value": 6
}
}
},
"randomname7": {
"type": "long",
"value": [0.0345034, 4.345345]
},
"randomname8": {
"type": "list",
"value": {
"type": "compound",
"value": [{
"randomnameA": {
"type": "int",
"value": 7
},
"randomnameB": {
"type": "int",
"value": 8
}
}, {
"randomnameC": {
"type": "int",
"value": 9
},
"randomnameD": {
"type": "int",
"value": 10
}
}]
}
}
}
};
tree.innerHTML = objectToHtml(data.value);
<div id="tree"></div>
I'm not certain I've exactly matched the HTML structure you're trying to create, but this should be close enough for you to modify to fit your needs.
The fastest approach is to construct a single string and drop it into the DOM, instead of doing incremental DOM operations:
var convert = function(input) {
var out = '';
out += '<ul>';
for (k in input) {
var obj = input[k];
out += '<li>' + k + ' - ' + obj.type + ' - ';
switch(obj.type) {
case "compound":
// recurse:
out += convert(obj.value); break;
case "long":
out += obj.value.join(' - '); break;
case "list":
out += obj.value.type + ' - ';
out += obj.value.value.join(' - '); break;
default:
// looks like all the other cases are identical:
out += obj.value;
}
out += '</li>';
}
out += '</ul>';
return out;
}
var data = {
"name": "",
"value": {
"randomname1": {
"type": "list",
"value": {
"type": "int",
"value": [26, 32, 25]
}
},
"randomname2": {
"type": "int",
"value": 5
},
"randomname3": {
"type": "string",
"value": "string or something"
},
"randomname4": {
"type": "compound",
"value": {
"randomname5": {
"type": "int",
"value": 6
},
"randomname6": {
"type": "int",
"value": 6
}
}
},
"randomname7": {
"type": "long",
"value": [0.0345034, 4.345345]
}
}
};
document.getElementById('output').innerHTML = convert(data.value);
<div id="output"></div>
Constructing this as an isolated document fragment rather than a single HTML string is, in this case, about 25% slower: https://jsperf.com/tree-test-fragment-vs-string/1
But with a little tweaking that slower method has the advantage of allowing you to use your setTimeout trick to defer each level of recursion, so the browser (one hopes) won't freeze up while trying to draw very large trees.
Here the recursion is handled in a separate function, so each setTimeout will be working with the correct data and DOM nodes (trying to do it all in the same function means that the iteration will have overwritten the variables with new data by the time the setTimeout fires -- this was part of why your original code wasn't recursing properly.) I added some deeper compound types to the data to demonstrate that this is working:
var convert = function(input) {
var fragment = document.createDocumentFragment();
var ul = document.createElement('ul');
fragment.appendChild(ul);
for (k in input) {
var obj = input[k];
var li = document.createElement('li');
var txt = k + ' - ' + obj.type + ' - ';
if (obj.type === 'compound') {
li.innerHTML = txt;
recurse(li, obj.value); // acts as a closure for these vars
} else {
switch (obj.type) {
case "long":
txt += obj.value.join(' - ');
break;
case "list":
txt += obj.value.type + ' - ';
txt += obj.value.value.join(' - ');
break;
default:
txt += obj.value;
}
li.innerHTML = txt;
}
ul.appendChild(li);
}
return fragment;
}
var recurse = function(li, d) {
window.setTimeout(function() {
li.appendChild(convert(d));
}, 1);
}
var data = {
"name": "",
"value": {
"randomname1": {
"type": "list",
"value": {
"type": "int",
"value": [26, 32, 25]
}
},
"cptest1": {
"type": "compound",
"value": {
"x": {
"type": "int",
"value": 2
},
"cptest2": {
"type": "compound",
"value": {
"y": {
"type": "int",
"value": 2
},
"z": {
"type": "int",
"value": 3
}
}
},
}
},
"randomname3": {
"type": "string",
"value": "string or something"
},
"randomname4": {
"type": "compound",
"value": {
"randomname5": {
"type": "int",
"value": 6
},
"randomname6": {
"type": "int",
"value": 6
}
}
},
"randomname7": {
"type": "long",
"value": [0.0345034, 4.345345]
}
}
};
document.getElementById('output').appendChild(convert(data.value));
<div id="output"></div>
Im experimenting with the espn public API and am trying to use their json to access NFL player information.
the json im accessing succesfully looks like:
{
"sports": [
{
"name": "football",
"id": 20,
"leagues": [
{
"name": "National Football League",
"abbreviation": "nfl",
"id": 28,
"groupId": 9,
"shortName": "NFL",
"athletes": [
{
"id": 14466,
"firstName": "Isa",
"lastName": "Abdul-Quddus",
"fullName": "Isa Abdul-Quddus",
"displayName": "Isa Abdul-Quddus",
"shortName": "I. Abdul-Quddus",
"links": {
"api": {
"athletes": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/14466"
},
"news": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/14466/news"
},
"notes": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/14466/news/notes"
}
},
"web": {
"athletes": {
"href": "http://espn.go.com/nfl/player/_/id/14466/isa-abdul-quddus?ex_cid=espnapi_public"
}
},
"mobile": {
"athletes": {
"href": "http://m.espn.go.com/nfl/playercard?playerId=14466&ex_cid=espnapi_public"
}
}
}
},
{
"id": 8645,
"firstName": "Hamza",
"lastName": "Abdullah",
"fullName": "Hamza Abdullah",
"displayName": "Hamza Abdullah",
"shortName": "H. Abdullah",
"links": {
"api": {
"athletes": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/8645"
},
"news": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/8645/news"
},
"notes": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/8645/news/notes"
}
},
"web": {
"athletes": {
"href": "http://espn.go.com/nfl/player/_/id/8645/hamza-abdullah?ex_cid=espnapi_public"
}
},
"mobile": {
"athletes": {
"href": "http://m.espn.go.com/nfl/playercard?playerId=8645&ex_cid=espnapi_public"
}
}
}
},
{
"id": 11910,
"firstName": "Husain",
"lastName": "Abdullah",
"fullName": "Husain Abdullah",
"displayName": "Husain Abdullah",
"shortName": "H. Abdullah",
"links": {
"api": {
"athletes": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/11910"
},
"news": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/11910/news"
},
"notes": {
"href": "http://api.espn.com/v1/sports/football/nfl/athletes/11910/news/notes"
}
} ........
]
}
]
}
],
"resultsOffset": 0,
"resultsLimit": 50,
"resultsCount": 3301,
"timestamp": "2013-01-06T19:30:17Z",
"status": "success"
}
and heres the html / javascript Im using:
$(document).ready(function(){
$.getJSON("http://api.espn.com/v1/sports/football/nfl/athletes?apikey=MY-API-KEY-HERE&_accept=application/json",
function(data){
$.each(data["sports"], function(i,item){
$("#infoDiv").append( [i] + " - " + item.name + "<br>" );
});
});
});
i can get this to display 0 - football but cant use something like
$.each(data["sports"]["leagues"]["athletes"], function(i,item){
$("#infoDiv").append( [i] + " - " + item.firstName + "<br>" );
to access the individual athlete data such as item.firstName , etc.
i keep getting the following error:
TypeError: data.sports.leagues is undefined
what am I missing? I'm using this same code structure successfully with a couple of other API's that provide json. the ESPN json is a little more complex in comparison though.
thanks for any light you can shed on this for me.
sports, leagues and athletes are arrays, for example: sports[0] is an object (the one with name='football')
You should iterate each like this (not tested):
$.each(data.sports, function(i,sport) {
$.each(sport.leagues, function(i,league) {
$.each(league.athletes, function(i,athlete) {
$("#infoDiv").append( [i] + " - " + athlete.firstName + "<br>" );
});
});
});
sports, leagues and athletes are arrays which you need to iterate.
for (var i=0; i<data.sports.length; i++) {
var sport = data.sports[i];
$("#infoDiv").append( [i] + " - " + sport.name + "<br>" );
for (var j=0; j<sport.leagues.length; j++) {
var league = sport.leagues[j];
$("#infoDiv").append( [i,j] + " - " + league.name + "<br>" );
for (var k=0; k<league.athletes.length; k++) {
var athlete = league.athletes[k];
$("#infoDiv").append( [i,j,k] + " - " + athlete.fullName + "<br>" );
}
}
}