I have the following JSON on a URL:
{
"href":"http:\/\/api.rwlabs.org\/v1\/jobs?limit=10",
"time":18,
"links":
{
"self":
{
"href":"http:\/\/api.rwlabs.org\/v1\/jobs?offset=0&limit=10&preset=minimal"
},
"next":
{
"href":"http:\/\/api.rwlabs.org\/v1\/jobs?offset=10&limit=10&preset=minimal"
}
},
"totalCount":2279,
"count":10,
"data":[
{
"id":"1148141",
"score":1,
"href":"http:\/\/api.rwlabs.org\/v1\/jobs\/1148141",
"fields":
{
"title":"Volunteer Renewable Energy Programmes Coordinator"
}
},
{
"id":"1147901",
"score":1,
"href":"http:\/\/api.rwlabs.org\/v1\/jobs\/1147901",
"fields":
{
"title":"Volunteer Project Management Coordinators \/ Intern"
}
}
/* so on*/
And I want get the information inside "data" and inside "fields".
If I remove the part before data array, I can get some of the values, but fields returns undefined. Although I also need to have a solution without removing the information before data.
JS
var table = '<table><thead><th>id</th><th>title</th></thead><tbody>';
var obj = $.parseJSON(data);
$.each(obj, function(i, val) {
table += '<tr><td>' + this['id'] + '</td><td>' + this['obj[i].title'] + '</td></tr>';
});
table += '</tbody></table>';
document.getElementById("datalist").innerHTML = table;
(I also do not know how to parse the data from the URL, so for now I am copying the data into the script)
[JSFiddle]: http://jsfiddle.net/1v803c3L/1/ Although I have part of the data on the code, even though the entire information is on an URL as seen on the code I posted.
obj.data[i].fields.title where i is an int that you use to index into the data array
Related
nested json structure
Json Structure:
{
"id": "30080",
"dataelements": {
"Name": "abc",
},
"children": [
{
"id": "33024",
"dataelements": {
"Name": "a",
},
"children": [
{
"id": "33024",
"dataelements": {
"Name": "b"
},
"children": [
{
"id": "33024",
"dataelements": {
"Name": "z"
},
"children": []
}
]
}
]
},
{
"id": "4800",
"dataelements": {
"Name": "d"
},
"children": [
{
"id": "4800",
"dataelements": {
.........................
I have my nested json data as shown in the image. For every child object, I create a node model. A child object can have additional child objects inside it.
if (ele == "dataelements")
{
var categoryNode = new NodeModel(
{
label: row.dataelements.Name,
icons: [{ iconName: 'product'}],
grid: row[ele]
});
}
if(ele == "children")
{
var subCategoryNode;
var subCategoryIndex = 1;
for (var i = 0, len = row.children.length; i<len; i++)
{
subCategoryNode = new NodeModel(
{
label: row.children[i].dataelements.Name,
icons: [{
iconName: '3dpart' }],
grid: row.children[i].dataelements
});
categoryNode.addChild(subCategoryNode);
}
}
This code handles only one level of child nodes.
How do I check for the inner children when I don't know exactly how many child levels are nested inside?
A quick run down on recursive functions and a gotcha to look out for
Recursive functions are great for nested data
They call themselves for each iteration of the input until it hits a base case
They can be tricky to wrap your head around at first
Recursive functions can hit the call stack limit if used poorly or the input is monstrous in size
Look out for variables used in the recursive calls, use let keyword to tell javascript to set the variable in the current scope
The Solution
Let's assume your JSON has been validated and this is the structure in the example below.
If I want to iterate through all elements in the JSON, I want to use a recursive call to make it neat, and simple to debug and simple to build on.
Here is an example of iterating through your given example JSON to print out an exploded view.
How to use the below code
Copy the recursiveSearch function
Call the recursiveSearch function passing in your JSON
Modify it to your needs, I gave you something to build on
CODE
var someJson = {"id": "30080","dataelements": {"Name": "abc"},"children": [{"id": "33024","dataelements": {"Name": "a"},"children": [{"id": "33024","dataelements": {"Name": "b"},"children": [{"id": "33024","dataelements": {"Name": "z"},"children": []}]}]}, {"id": "4800","dataelements": {"Name": "d"},"children": []}]};
//we set level to 0 (optional variable) this means we can omit it in the inital call for neat code
function recursiveScan(json, level=0)
{
//we store all of the output in a log and keep a track of the level to determine indenting
var log = "";
var indent = "";
//based on the current level of the recursion, we indent the text to make it readable
for (let i=0; i<level; i++)
{
indent += " ";
}
//avoid any bad json or invalid data by checking if the name and id is null
if(json.dataelements.Name != null && json.id != null)
{
//we know there is a valid element, write the name and id
log += indent + "ID: " + json.id + "<br>";
log += indent + "Name: " + json.dataelements.Name + "<br>";
//if there is any children
if(json.children.length > 0)
{
//just for neatness, lets draw the paranthesis
log += indent + "{" + "<br>";
//increase the level
level++;
//for each child, recursively call this function to get the next level of children if available
for(let t=0; t<json.children.length; t++)
{
log += recursiveScan(json.children[t], level);
}
//we are dropping our recursion level now, getting ready to return;
level--;
//close the paranthesis for neatness
log += indent + "}" + "<br>";
}
}
//return the final log
return log;
}
//now lets test the code
document.write(recursiveScan(someJson));
The above code produces
ID: 30080
Name: abc
{
ID: 33024
Name: a
{
ID: 33024
Name: b
{
ID: 33024
Name: z
}
}
ID: 4800
Name: d
}
Now a simple run-down without all the noise
function recursiveScan(json)
{
if(json.dataelements.Name != null && json.id != null)
{
//here you have access to id and dataelements
if(json.children.length > 0)
{
for(let t=0; t<json.children.length; t++)
{
//here you have access to each child as json.children[t]
//you could do the logic for the current child
//then pass the current child to the recursive function
recursiveScan(json.children[t]);
}
}
}
return true;
}
SITUATION:
I have dynamic json object data and need to use it to find element.
Example:
[
{ "tag": "article",
"id": "post-316",
"order": "0" },
{ "tag": "div",
"class": "entry-content",
"order": "0" }
]
Its length, keys and values can change anytime based on user request.
I need to use that data to dynamically find the specified element in a web page. The first set of strings will be the data for parent element, which will be used to initialize the search, and the last one will be the target children.
PURPOSE:
So, from json example above, I want to find an element with:
class name entry-content, tag name div, index 0 inside of parent with id post-316
by converting that json data in such kind of format or may be simpler and or better:
// because the parent already have attribute id, so no need to check other info of this element
var elem = $("#post-316").find(".entry-content");
if(elem.prop("tagName") == "div" ) {
elem.css("background", "#990000");
}
PROGRESS:
I tried using jquery $.each() method but can't discover myself the way to achieve that purpose.
Here is the code where I currently stuck on:
var json = $.parseJSON(theJSONData);
$.each(json, function(i, e){
$.each(e, function(key, data){
alert(i + " " + key + " " + data);
if(json.length - i == 1) {
alert("target " + data);
}
if(json.length - i == json.length) {
alert("parent " + data);
}
}
);
});
QUESTIONS:
Is it possible to achieve the PURPOSE from that kind of JSON data using iteration?
If it is possible, how to do it?
If not, what the way I can use?
You can use a format so the script knows what to get:
var data = {
'id': '#',
'class': '.'
};
var json = JSON.parse(theJSONData);
$.each(json, function (a) {
$.each(data, function (b) {
if (a[b]) {
$(data[b] + a[b])[+a['order']]; // Element
}
});
});
If you are sure about the data you are getting (As in it is class, or data, and it will have a tag name):
var json = JSON.parse(theJSONData),
last = document;
$.each(json, function (a) {
var selector = (a['id']) ? '#'+a['id'] : '.'+a['class'];
last = $(last).find(a['tag']+selector)[+a['order']]; // Element
});
I have json data that looks like this
{
"projects":{
"COMMERCIAL":[
{
"ppID":"87",
"pTitle":"5th Street Lofts"
},
{
"ppID":"94",
"pTitle":"Skip-a-Long Child Development Services"
}
],
"CORPORATE":[
{
"ppID":"86",
"pTitle":"Caxton Building"
},
{
"ppID":"68",
"pTitle":"Swiss Valley Corporate Headquarters"
}
],
"EDUCATION (COLLEGIATE)":[
{
"ppID":"20",
"pTitle":"Ashford University - Athletic Field"
},
{
"ppID":"64",
"pTitle":"St. Ambrose University - Center For Health And Science Education"
}
]
},
"error":"0"
}
In this example, "COMMERCIAL", "CORPORATE", and "EDUCATION (COLLEGIATE)" are unknown fields names.
I'm getting it from my CGI, which looks like this:
$.ajax({
url: "cgi/myCGI.exe",
dataType: "json",
error: ajaxError,
success: function(json){
if(json.error !== "0"){
alert("error processing request: "+json.error);
return;
}
var temp="";
var i=0;
for(i=0;i<=json.projects.length-1;i++){
// tried something like this
}
$.each(json.projects, function(ppID, pTitle) {
// tried something like this
});
// add to my html
}
});
Ultimately, I want to add HTML to the webpage,
like
<div class="smSubTitle">COMMERCIAL</div>
Fidlar Technologies<br>
Skip-a-Long Child Development Services<br>
<div class="smSubTitle">CORPORATE</div>
etc.
I can't figure out how to get the names of each project "sub title" then it's individual field values.
EDIT:
First, I noticed that json.projects.length is undefined.
I also tried json.projects[0].length but it is also undefined.
in
$.each(json.projects, function(ppID, pTitle) {
console.log("test: "+ppID);
console.log("test: "+pTitle);
});
ppID works, but pTitle says [object,object]
projects property is an object and each object property contains an array. So you have to at first iterate through the object's keys and then the arrays, i.e. 2 nested loops:
var html = '', projects, type, i;
for ( type in json.projects ) {
if ( json.projects.hasOwnProperty(type) ) {
// append the type of the projects
html += "<div class='smSubTitle'>" + type + "</div>";
projects = json.projects[type];
// iterate through each array
for ( i = 0; i < projects.length; i++ ) {
html += "<a href='somePage.html?id="+ projects[i].ppID+ "'>"+ projects[i].pTitle +"</a><br>";
}
}
}
Here is a demo.
I think you have a misunderstanding of what JSON is. JSON is a string and not an object hence it's abbreviation of JavaScript Object Notation. What you have is colloquially referred to as a POJO or Plain Old Javascript Object. They are different.
That said, you can iterate over these objects like so:
Object.keys(json.projects).forEach(function(key, i) {
// key is "COMMERCIAL", "CORPORATE", ...
// You can add the smSubTitle element here
json.projects[key].forEach(function(item) {
// item is an object {ppID: '...', pTitle: '...'}
// You can add a link per object here
});
});
I am trying loop through the following JSON file below:
{
"statements": [{
"subject": "A"
}, {
"predicate": "B"
}, {
"object": "C"
}, {
"subject": "D"
}, {
"predicate": "E"
}, {
"object": "F"
}]
}
As you can see, there are two subjects, two predicates and two objects. I would like to get, for instance, the value "predicate":"E". How can I do this using jQuery or D3 Javascript library. My code below retrieves the first subject "subject":"A".
$.each(data.statements[0], function(i, v){
console.log(v.uriString);
});
or in D3 (I do not know how to do this in D3):
d3.json("folder/sample.json", function(error, graph)
{ // Code is here for getting data from JSON file }
Could anyone please help me loop through the JSON file above and retrieve some particular data either with jQuery or D3 Javascript. Thank you for your help in advance.
Try this:
$(data.statements).each(function (i) {
var d = data.statements[i];
$.each(d, function (k, v) { //get key and value of object
$("body").append("<p>"+k + ":" + v+"</p>");
});
})
Fiddle here.
The reason why your code returns the first item is beacuse you selected it with data.statments[0] and afterwards loop over that one item.
With jQuery you can use the grep-method like this:
var arrayWithItem = jQuery.grep(data.statements, function( obj ) {
return obj.predicate == "E";
});
You can read more about the grep-method here
With D3js I'm not sure, I guess you have to loop through it with an if-statement.
I’m requesting JSON from Wikipedia’s API at
http://en.wikipedia.org/w/api.php?action=query&prop=description&titles=WTO&prop=extracts&exsentences&explaintext&format=json
The response looks like this:
{
"query": {
"pages": {
"ramdom_number_here": {
"pageid": ramdom_number_here,
"ns": 0,
"title": "Hello",
"extract": "Hello world! Enchanté to meet you"
}
}
}
}
Given that ramdom_number_here changes each request (so we don't know it), how can extrac or title’s data be accessed?
Use Object.keys(data)[x] to replace the nominative pathway byt the the coordinate of your data.
Object.keys(data) -- give you the list of keys at that level.
Then use x=the numeral rang of your target data. For the first data point, then [x]=[0].
Solution> JSfiddle:
function WD(val) { // input
target_API_url = "http://zh.wikipedia.org/w/api.php?action=query&prop=description&titles=" + val.toString() + "&prop=extracts&exintro&explaintext&format=json&redirects&callback=?";
$.getJSON(target_API_url, function (json) {
trad = json.query.redirects[0].to; // no "var", variable is global
var item_id = Object.keys(json.query.pages)[0]; // THIS DO THE TRICK !
sent = JSON.stringify(json.query.pages[item_id].extract);
result = "<b>En:</b> "+val.toString() + ", <b>Zh: </b>"+trad.toString() + "<br /><b>⇒</b>" + sent.toString();
$('p').html(result); // transformation
});
};
WD("WTO");
Encouraging +1 welcome.
In javascript you can:
var a; // assume that a is your json
var title;
for (var obj in a["query"]["pages"])
{
if (a["query"]["pages"][obj].title != undefined)
{
title = a["query"]["pages"][obj].title;
break;
}
}