Creating html elements through nested JSON objects - javascript

So I've managed to successfully create HTML elements through JSON objects before, but now that I've changed my JSON objects to nested JSON, I am not able to reproduce the HTML elements accordingly. I am pretty new to programming so can anyone help me find out where I have gone wrong?
JSON File:
{
"ThreeG": [
{
"title":"Testing 1",
"filePath":"https://example.com",
"imagePath":"images/test.jpg"
},
{
"title":"Testing 2",
"filePath":"https://example.com",
"imagePath":"images/test2.jpg"
}
]
}
Script:
<script>
$.ajax({
url : "TestFiles.json",
type : "post",
contentType:"application/json",
success : function(list){
var divCol = "<div class='col-md-offset-1 col-sm-5 col-md-5'>";
var divWell = "<div class='well' style='position:relative'>";
var divClose= "</div>";
list.forEach(function(obj, index) {
var title = "<h4>" + obj.ThreeG.title + "</h4>";
var linkStart = "<a href='" + obj.ThreeG.filePath + "' target='_blank'>" ;
var image = "<img data-toggle='tooltip' data-placement='left' title='Click to open data' src='" + obj.ThreeG.imagePath + "' height='100%' width='100%'/>"
var linkEnd = "</a>";
var div = divCol +
divWell +
title +
linkStart +
image +
linkEnd +
divClose +
divClose;
console.log(obj);
$("#test").append(div);
})
}
});
</script>

The list param in the success callback is an object with property / key ThreeG. So instead of list.forEach, you should do list.ThreeG.forEach, then each obj in the forEach callback will be the json object that you can use to create HTML elements.
list.ThreeG.forEach(function(obj, index) {
console.log(obj); // { "title":"Testing 1", "filePath":"https://example.com", "imagePath":"images/test.jpg" } for the first object
}

var obj = {
"ThreeG": [
{
"title":"Testing 1",
"filePath":"https://example.com",
"imagePath":"images/test.jpg"
},
{
"title":"Testing 2",
"filePath":"https://example.com",
"imagePath":"images/test2.jpg"
}
]
};
for(var i=0;i<obj.ThreeG.length;i++) {
var data = obj.ThreeG[i];//Take a reference here
console.log(data.title, data.filePath, data.imagePath);
}
You cannot say obj.ThreeG.title since obj.ThreeG is an array. You need to use obj.ThreeG[0].title and obj.ThreeG[1].title etc.
Do some looping as shown above.

Related

Processing Ajax Data Using External Function Results in Error

I have an Ajax function below which returns data. I can log data to the console, but I want to process the "skilllist" in a separate function to generate HTML to add to the overall string. The function returns the HTML, but when it does so it generates an error just because the function is called.
My AJAX function looks like:
$("#search").click(function() {
$.ajax({
type: "POST",
dataType: "json",
url: "/search/projectsearchsimple/",
data: { csrfmiddlewaretoken:'{{ csrf_token }}',
search : $("#id_search").val() },
success: function(data) {
//update_messages(data.messages);
console.log(data);
$("#resultsarea").show();
$("#resultspanel").empty();
data = JSON.parse(data);
var resultshtml = "";
for(i=0;i<data.length;i++) {
var skilllist = [...data[i].skilllist];
var skillsbox = createSkillsBox(skilllist);
resultshtml = resultshtml + "<div class='row'><div class='col-2'>" +
"<a href='/project/projectpage/" + data[i].id + "'>" +
data[i].name + "</a>" + "</div>" + "<div class='col-2'>by " +
data[i].owner__username + "</div><div class='col-3'>Created on: " +
data[i].created + "</div></div>";
}
$("#resultspanel").append(resultshtml);
}
});
});
The external function looks as:
function createSkillsBox(skills) {
skillsboxhtml = "<div class='menu-outer'><div class='table'><ul id='skills{{ job.id }}' class='horizontal-list skillsboxuser'>";
for(i=0;i<skills.length;i++) {
skillsboxhtml += "<li><strong>" + skills[i] + "</strong></li>"
}
skillsboxhtml += "</ul></div></div>";
return skillsboxhtml;
}
The error received in the console sates "TypeError: data[i] is undefined[Learn More]". If I comment out the line "var skillsbox = createSkillsBox(skilllist);" it works doesn't error.
The data variable contains:
[{"skilllist": ["Programming", "Musician", "Writing"], "name": "Project KFC", "id": 3, "owner__username": "kyle", "created": "18/11/19 10:00", "description": "description"}]
I have tried moving the function to inside the Ajax method and I have tried with passing data[i] direct before i tried the shallow copy.
Can anyone help?

Iterate Json Data in JavaScript/TypeScript

I need to Iterate on this Json Data and add value to the Grid in JavaScript(TypeScript) No Jquery.
{"GridHeader":{"Id":"Id","Name":"Full Name","Age":"Age"},"GridData":{"Id":3,"name":"Vu","age":34}}
I have the Add function as follows which add header and Data to the Grid:
let header = '{"GridHeader":{"Id":"Id","Name":"Full Name","Age":"Age"},"GridData":{"Id":3,"name":"Vu","age":34}}';
let myheader = JSON.parse(header);
for (var i = 0; ??) {
....
AddRecord(headerdata, i);
}
This is where I am adding it to the Grid:
function AddRecord(record, n) {
var detail = document.getElementById("detail");
var header = document.getElementById("header");
if (n == 0) {
var newdiv = document.createElement("div");
newdiv.innerHTML = "<div style=''>" + record.id + "</div>" + "<div>" + record.name + "</div>" + "<div>" + record.age + "</div>";
}
var newdiv = document.createElement("div");
newdiv.innerHTML = "<div style=''>" + record.id + "</div>" + "<div>" + record.name + "</div>" + "<div>" + record.age + "</div>";
detail.appendChild(newdiv);
}
Yes, your data is actually a javascript object below:
var header = {
"GridHeader":{"Id":"Id","Name":"Full Name","Age":"Age"},
"GridData": {"Id":3,"name":"Vu","age":34}
};
And you can loop through it like below:
for (var prop in header) {
console.log("Key:" + prop);
console.log("Value:" + header[prop]);
}
Please, make it according to your needs. I have give you a clue to iterate it. Thanks.
Your going to have to explain in more detail what you mean by "iterate on the data".
{
"GridHeader":{
"Id":"Id",
"Name":"Full Name",
"Age":"Age"
},
"GridData":{
"Id":3,
"name":"Vu",
"age":34
}
}
Does not have any Arrays present in it.
If it did have arrays in it, then I'm going to assume you meant something like this:
"mydata":{
"GridHeader":{
"Id":"Id",
"Name":"Full Name",
"Age":"Age"
},
"GridData":[
{
"Id":3,
"name":"Vu",
"age":34
},
{
"Id":2,
"name":"Vu2",
"age":33
},
{
"Id":1,
"name":"Vu1",
"age":32
}
]
}
If your data looks like that, then you have an array of objects in your grid data, and you would then be able to use something like this:
mydata.GridData.forEach(item){
// DO something with
// item.Id
// item.Name
// item.Age
}
Within the loop your code will get called once for each object in the GridData part of your parent and allow you access to each of the 3 properties for each individual item.
However, looking at your data the way it is, then it's just a simple object.
If we imagine you have it in a variable called myData, then you can access it's parts as follows:
myData.GridHeader.Id
myData.GridHeader.Name
myData.GridHeader.Age
To get the header properties.
myData.GridData.Id
myData.GridData.Name
myData.GridData.Age
To get at the properties of the one and only non iterable object you have present.

Printing HTML Attritbutes with jquery in a loop

i try to loop trough Objects in a Database (parse.com) and would like to print these results with attributes from Bootstrap. I'm a beginner and don't understand why it's not possible how i did it. i know there is .attr() but i don't get it how i can use this in my example.
This is my code:
var Insider = Parse.Object.extend("Insider");
function getPosts() {
var query = new Parse.Query(Insider);
query.find({
success: function(results) {
var output = "";
for (var i in results) {
var name = results[i].get("name");
var catego = results[i].get("cate");
var imageurl = results[i].get("image");
var tpp = results[i].get("tipp");
output += "<ul class="media-list">";
output += "<li class="media">";
output += "<div class="media-left">";
output += "<a href="#">";
output += "<img id = "two" class="media-object"
alt="...">"
output += "<h4>+ + name + "</h4>";
output += "</a>"
output += "</div>"
}
$("#list").html(output);
},
error: function(error){
console.log("Query error:" + error.message);
}
});
}
getPosts();
});
Any help much appreciated!

Looping through nested array vaues in JSON, appending those values to generated html

EDITED:
I'm (still) having a little trouble getting values from a nested array in JSON and appending them to generated html.
I'm currently using the following JSON (updated):
{
"OuterArray": [
{
"memberId": "01",
"key01": "",
"included": "true",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
},
{
"memberId": "02",
"key01": "",
"included": "true",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
},
{
"memberId": "03",
"key01": "",
"included": "false",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
},
{
"memberId": "04",
"key01": "",
"included": "true",
"nestedArray": [
{ "keyA": "", "keyB": "" },
{ "keyA": "", "keyB": "" }
]
}
]
}
And this js:
for (var i = 0; i < outerArray.length; i++) {
if (outerArray[i].included !== "false") {
var key01 = outerArray[i].key01;
var key02 = outerArray[i].key02;
// etc.
var nestedArray = outerArray[i]["nestedArray"];
myDiv.innerHTML +=
"<div class=\"outer-array-stuff\">"
+ "<p class=\"key01\">" + key01 + "</p>"
+ "<p class=\"key02\">" + key02 + "</p>"
+ "<div class=\"nested-array-stuff\">" // help?
+ "</div>"
+ "</div>"
var nestedArrayStuff = document.getElementsByClassName("nested-array-stuff")[i];
for (var j=0; j<outerArray.length; j++) {
nestedArrayStuff.innerHTML += "<p class=\"keyA\">" + nestedArray[j].keyA + "</p>";
}
}
Note that one of the keys in the outer array has a boolean value which determines whether or not it (the outer array member) is - and its nested array stuff are - included in the page.
So just to reiterate, the goal is:
<div class="outer-array-stuff">
<!-- <snip: some outer array key/values here /> -->
<div class="nested-array-stuff">
<div class="nested-array-stuff">
<p>[e.g., nested array key 1 value]</p>
<p>[e.g., nested array key 2 value]</p>
<p>[etc.]</p>
</div>
</div>
If all the outer array members 'included' are 'true', everything outer & nested loads, but this is not exactly what I want; I need to filter so that only those 'included' !== "false". So now my problem is that despite being inside the if 'included'/else loop, the outer array members stop loading at the first excluded outer array member (actually, the next 'true' outer array member does load, but its nested array stuff doesn't, and then nothing further loads, the entire outer array loop dies.
Any insight as to why this is happening?
Many thanks to dreyescat for the help to this point.
P.S. generally I'm trying to minimize my reliance on jQuery.
Many thanks, svs
You are almost there. Here is your code revised with some comments.
// Generally is not a good practice iterate arrays using for..in
//for (var i in outerArray) {
for (var i = 0; i < outerArray.length; i++) {
var key01 = outerArray[i].key01;
var key02 = outerArray[i].key02;
// This should by outerArray array and not jsonData object.
var nestedArray = outerArray[i]["nestedArray"];
myDiv.innerHTML +=
"<div class=\"outer-array-stuff\">"
+ "<p class=\"key01\">" + key01 + "</p>"
+ "<p class=\"key02\">" + key02 + "</p>"
+ "<div class=\"nested-array-stuff\">" // help?
+ "</div>"
+ "</div>"
// getElementsByClassName gets a list of elements that have that class.
// I suppose you want to add the elements to the corresponding outer array.
// Let's use the loop index i to get the proper parent element. You could also
// just get the last one.
var nestedArrayStuff = document.getElementsByClassName("nested-array-stuff")[i]; // help?
// Again I recommend you not to use for..in for arrays.
for (var obj in nestedArray) {
nestedArrayStuff.innerHTML += "<p class=\"keyA\">" + nestedArray[obj].keyA + "</p>"; // NOPE
}
}
See demo.
You could also build the entire nested array stuff before adding it to the div element. Then you don't need to query the document to get the nested array stuff element.
for (var i in outerArray) {
var key01 = outerArray[i].key01;
var key02 = outerArray[i].key02;
var nestedArray = outerArray[i]["nestedArray"];
var nestedArrayStuff = '<div class=\"nested-array-stuff\">';
for (var obj in nestedArray) {
nestedArrayStuff += "<p class=\"keyA\">" + nestedArray[obj].keyA + "</p>"; // NOPE
}
nestedArrayStuff += '</div>';
myDiv.innerHTML += "<div class=\"outer-array-stuff\">"
+ "<p class=\"key01\">" + key01 + "</p>"
+ "<p class=\"key02\">" + key02 + "</p>"
+ nestedArrayStuff
+ "</div>"
+ "</div>";
}
See demo
nestedArray is not a string. your nestedArray array loop should be as follows.
var nestedArray = outerArray[i].nestedArray;
for (var j in nestedArray) {
console.log(nestedArray[j].keyA);
console.log(nestedArray[j].keyB);
}
Here is your complete solution, I used lists to output content. It assumes we have one container:
<div id="mydiv"></div>
Than JS would be:
var myDiv = document.getElementById('mydiv');
var outerArray = [
{
"memberId":"01",
"key01":"",
"key02":"key02 exists, ...",
"included":"true",
"nestedArray":[
{
"keyA":"1",
"keyB":"2"
},
{
"keyA":"3",
"keyB":"4"
}
]
},
{
"memberId":"02",
"key01":"key01 value..",
"included":"true",
"nestedArray":[
{
"keyA":"5",
"keyB":""
},
{
"keyA":"",
"keyB":"8"
}
]
},
{
"memberId":"03",
"key02":"",
"included":"false",
"nestedArray":[
{
"keyA":"",
"keyB":"9"
},
{
"keyA":"",
"keyB":""
}
]
},
{
"memberId":"04",
"key01":"value of key01",
"key02":"key02 value ...",
"included":"true",
"nestedArray":[
{
"keyA":"",
"keyB":"10"
},
{
"keyA":"11",
"keyB":"12"
}
]
}
];
var insertHtml = '';
for (var i = 0; i < outerArray.length; i++) {
if (outerArray[i].included !== "false") {
insertHtml += "<ul class=\"outer-array-stuff\">";
insertHtml += " <li>";
insertHtml += " <p class=\"memberId\">memberId(" + i + "): " + outerArray[i].memberId + "</p>"
insertHtml += " <p class=\"key01\">key01: " + ( ( typeof outerArray[i].key01!='undefined' && outerArray[i].key01 ) ? outerArray[i].key01 : '') + "</p>"
insertHtml += " <p class=\"key02\">key02: " + ( ( typeof outerArray[i].key02!='undefined' && outerArray[i].key02 ) ? outerArray[i].key02 : '') + "</p>"
var nestedArray = outerArray[i]["nestedArray"];
if ( nestedArray.length>0 ) {
insertHtml += " <ul class=\"nested-array-stuff\">"
for (var j=0; j<nestedArray.length; j++) {
insertHtml += "<li class=\"keyA\">keyA(" + j + "): " + nestedArray[j].keyA + "</li>";
insertHtml += "<li class=\"keyB\">keyB(" + j + "): " + nestedArray[j].keyB + "</li>";
};
insertHtml += " </ul>"
};
insertHtml += " </li>";
insertHtml += "</ul>"
}
}
myDiv.innerHTML = insertHtml;

access nested json data from ajax call

I am interfacing with an API which returns JSON data to me. As the results are not stored in a file, but rather server memory, I am having a hard time figuring out how to access the data and write it to my html webpage. Here's what my $.ajax call looks like:
$.ajax({
type: "post",
url:"https://www.xxx/v1/trips/search? key=xxxx",
data:JSON.stringify({request : requestTrav1Dest1}),
dataType:"json",
success:successFunction,
headers:{"Content-Type":"application/json"}
});
Here's what the JSON I get back from the server looks like:
{
"kind": "#tripsSearch",
"trips": {
"kind": "#tripOptions",
"tripOption": [
{
"saleTotal": "USD294.10",
"id": "DMfSXrkVQGKTVQsDD5l60N004",
},
"saleTotal": "USD333.10",
"id": "DMfSXrkVQGKTVQsDD5l60N002",
},
{
"saleTotal": "USD225.94",
"id": "DMfSXrkVQGKTVQsDD5l60N005",
}
]
}
}
What I really need is the saleTotal for each tripOption.
I broke out the function that runs if the query is a success here:
function successFunction(servResponse){
$('#content').load('resultsPage.html #content');
var newContent = '';
for(var i = 0; i < servResponse.trips.tripOption[i].length; i++){
newContent += '<div class="results">';
newContent += '<p>' + "Option " + (i+1) + '<br>';
newContent += servResponse.trips.tripOption[0].saleTotal + '<br>';
newContent += '</div>';
}
document.getElementById('content').innerhtml = newContent;
}
Unfortunately, this does not write out anything to the webpage. So far I can only view the raw JSON results in the Chrome Developer's Toolbar Console.
Can someone please help identify what I need to do differently?
Thanks in advance!
Assuming you have an element on the page with the ID of content, it should work fine, you just have a little typo
document.getElementById('content').innerhtml = newContent;
capitlize the 'HTML',
document.getElementById('content').innerHTML = newContent;
$('#content').load('resultsPage.html #content'); looks incorrect, the 1st parameter should just be a URL. Try commenting it out, for now, since you're changing it's content with the other line.
Also, the 4th line should be:
for(var i = 0; i < servResponse.trips.tripOption.length; i++){
You have:
... tripOption[i].length ...
The function below should:
Create one div with the class="results"
Place several p elements inside this div, each containing a 2-line entry
Display all this inside the element with an id of "content"
Is this what you want? The CSS that you are currently applying to .results may need to be applied to .results p instead.
function successFunction(servResponse){
var tripOption = servResponse.trips.tripOption;
var newContent = '<div class="results">';
for(var i = 0; i < tripOption.length; i++){
newContent += '<p>' + "Option " + (i+1) + '<br>';
newContent += tripOption[i].saleTotal + '<p>';
}
newContent += '</div>';
document.getElementById('content').innerHTML = newContent;
}
jsFiddle
var servResponse = {
"kind": "#tripsSearch",
"trips": {
"kind": "#tripOptions",
"tripOption": [
{
"saleTotal": "USD294.10",
"id": "DMfSXrkVQGKTVQsDD5l60N004",
},{
"saleTotal": "USD333.10",
"id": "DMfSXrkVQGKTVQsDD5l60N002",
},
{
"saleTotal": "USD225.94",
"id": "DMfSXrkVQGKTVQsDD5l60N005",
}
]
}
};
function successFunction(servResponse) {
var newContent = '';
servResponse.trips.tripOption.forEach(function(el,index){
newContent += '<div class="results">';
newContent += '<p>' + "Option " + (index+1) + '<br>';
newContent += el.saleTotal + '<br>';
newContent += '</div>';
console.log(el.saleTotal);
});
document.getElementById('content').innerHTML = newContent;
}
successFunction(servResponse);
Using pure javascript forEach loop
Example Link : http://jsfiddle.net/c1wzsqaf/1/

Categories