Parsing and displaying JSON data - json

I am looking to display the data from my JSON file. The data I would like to display is the title from my JSON file however I am unsure of how to parse it. I think the part I am getting wrong is the 'data[i].archives.year1.title' etc but I am unsure of how to solve this.
This is what I have already tried:
My JSON file
[
{
"archives": {
"year1": {
"title": "Sample Title 1"
},
"year2": {
"title": "Sample Title 2"
},
"year3": {
"title": "Sample Title 3"
}
},
"collections": {
"health": {
"title": "Sample Title 4"
},
"money": {
"title": "Sample Title 5"
},
"relationships": {
"title": "Sample Title 6"
}
}
}
]
HTML
<div class="archives"></div>
<div class="collections"></div>
JavaScript file
fetch('example.json')
.then(function (response) {
return response.json();
})
.then(function (data) {
appendData(data);
})
.catch(error => console.log('Looks like there was a problem: ', error));
function appendData(data) {
var mainContainer = document.getElementById("archives");
for (var i = 0; i < data.length; i++) {
var div = document.createElement("div");
div.innerHTML =
'<span class="archives">' + data[i].archives.year1.title + '</span>' +
'<span class="archives">' + data[i].archives.year2.title + '</span>' +
'<span class="archives">' + data[i].archives.year3.title + '</span>';
mainContainer.appendChild(div);
}
}
function appendData(data) {
var mainContainer = document.getElementById("collections");
for (var i = 0; i < data.length; i++) {
var div = document.createElement("div");
div.innerHTML =
'<span class="collections">' + data[i].collections.health.title + '</span>' +
'<span class="collections">' + data[i].collections.money.title + '</span>' +
'<span class="collections">' + data[i].collections.relationships.title + '</span>';
mainContainer.appendChild(div);
}
}
I expect the output to display all of the titles from "archives" and all of the titles from "collections". I am new to JavaScript.

Your for loops here:
for (var i = 0; i < data.length; i++) //archives
for (var i = 0; i < data.length; i++) //collections
should be:
for (var i = 0; i < data.archives.length; i++) //archives
for (var i = 0; i < data.collections.length; i++) //collections
then you can reference values with:
div.innerHTML =
'<span class="archives">' + data.archives[i].year1.title + '</span>' +
'<span class="archives">' + data.archives[i].year2.title + '</span>' +
'<span class="archives">' + data.archives[i].year3.title + '</span>';
Also bonus points for looking into VueJS or ReactJS and also learning to use console.log in your browser's debug tools.
Edit:
After reading your comment and re-reading your JSON file I realize you have it nested inside an array. You can either delete the square brackets containing your object you intend to use, or use:
for (var i = 0; i < data[0].collections.length; i++)
'<span class="archives">' + data[0].archives[i].year1.title + '</span>'
The square brackets create an array containing the object you are trying to access, where you could append more objects, but since you're using an object of objects already the array containing it seems redundant.

Related

AJAX: JSON loop that duplicate the same result

Problem solved, my json array was badly done.
I had just wrongly done my array in php, so I did it again and everything works.
<?php
$history = array();
$history[] = array('name' => $fetch[$s]['value'], 'url' => $url);
echo json_encode(['history' => $history]);
?>
function load_history() {
$.getJSON(URL + 'load.search.historique.php', function(data) {
if (data.type == 'success') {
for (var i = 0; i < data.history.length; i++) {
$('.search-item-result').append('<div class="search-item"><a name="' + data.history[i].name + '" action="redirect" href="' + data.history[i].url + '">' + data.history[i].name + '</a><i class="fas fa-times"></i></div>');
}
} else if (data.type == 'error') {
$('.search-item-result').html('<div class="search-item">' + data.message + '</div>');
}
});
}
Problem is in your JSON data formatting. Format as shown below, you will get desired output. You can view by run the snippet.
var data = {
"type": "success",
"message": "Permission denied: HTTP Exception",
"history": [
[
"Dr. STONE",
"https://mon-site.fr/watch/117-Dr.-STONE/episode-1/saison-1"
],
[
"One Piece ",
"https://mon-site.fr/watch/27-One-Piece-/episode-1/saison-1"
],
[
"One Piece ",
"https://mon-site.fr/watch/27-One-Piece-/episode-1/saison-1"
]
]
}
function load_history() {
if (data.type == 'success') {
var div = document.getElementById('myDiv');
for (var i = 0; i < data.history.length; i++) {
div.innerHTML += '<div class="search-item"><a name="' + data.history[i][0] + '" action="redirect" href="' + data.history[i][1] + '">' + data.history[i][0] + '</a><i class="fas fa-times"></i></div>';
}
} else if (data.type == 'error') {
div.innerHTML += '<div class="search-item">' + data.message + '</div>';
}
}
load_history();
<div id="myDiv"></div>

Convert JSON data to table

I am trying to create table from my JSON data which looks like this:
It works for a specific JSON data:
var items = [
{"Name":"A","Type":2,"Result":"0"},
{"Name":"A","Type":1,"Result":"1"},
{"Name":"B","Type":2,"Result":"1"},
{"Name":"B","Type":1,"Result":"0"},
]
But, it doesn't create table correctly if the columns ("Type") is random
var items = [
{"Name":"A","Type":5,"Result":"1"}
{"Name":"A","Type":2,"Result":"0"},
{"Name":"A","Type":1,"Result":"1"},
{"Name":"B","Type":3,"Result":"1"},
{"Name":"B","Type":2,"Result":"1"},
{"Name":"B","Type":1,"Result":"0"},
]
Can someone tell me what's the issue with my code?
I want to create table for dynamic JSON data which may not have cell values for all the columns. With this code, I don't see entry in column 5 for A as 1.
function get_prop(obj, prop) {
return prop.split('.').reduce((o,k) => obj[k], obj);
}
function coll2tbl(json, row_header, col_header, cell) {
var table = {};
var row_headers = [];
var cols = {};
json.map(function(a) {
var h = get_prop(a, row_header);
if (h in table === false) {
table[h] = {};
row_headers.push(h);
}
var c = get_prop(a, col_header);
cols[c] = null;
table[h][c] = get_prop(a, cell);
});
var cells = [];
for (var row in table) {
cells.push(Object.values(table[row]));
}
console.log('row_headers' + row_headers);
console.log('Object.keys(cols)' + Object.keys(cols));
console.log('cells' + cells);
var headerRow = '<th>' + capitalizeFirstLetter('TestName') + '</th>';
var colKeys = Object.keys(cols);
colKeys.map(function(col) {
headerRow += '<th>' + capitalizeFirstLetter(col) + '</th>';
});
var bodyRows = '';
for (var i in cells) {
bodyRows += '<tr>';
bodyRows += '<td>' + row_headers[i] + '</td>';
for (var j in cells[i]) {
console.log('Processing row: ' + row_headers[i] + ' result: ' + cells[i][j] + ' i=' + i + ' j=' + j);
bodyRows += '<td>';
if (cells[i][j] === "1") {
bodyRows += '<font color="green">' + cells[i][j] + '</font>';
}
else if (cells[i][j] === "0") {
bodyRows += '<font color="red">' + cells[i][j] + '</font>';
}
else if (cells[i][j] === "-1") {
bodyRows += '<font color="orange">' + cells[i][j] + '</font>';
}
else {
bodyRows += "-";
}
bodyRows += '</td>';
}
bodyRows += '</tr>';
}
//return { row_headers, col_headers: Object.keys(cols), cells };
return ('<table> <thead><tr>' + headerRow + '</tr></thead><tbody>' + bodyRows + '</tbody></table>');
}
function capitalizeFirstLetter(string) {return
string.charAt(0).toUpperCase() + string.slice(1);
}
coll2tbl(items, 'Name', 'Type', 'Result');
My table should like like this:
Name 1 2 3 4 5
A 1 1 - - 1
B 1 1 1 - -
The answer https://stackoverflow.com/a/52199138/10320683 is of course correct, but if you need or want to stick to your specific code, you can put this below your json.map (which should by the way use forEach and not map, since you do not use the returned array anyways)
for (var col in cols) {
for (row in table) {
if (!table[row].hasOwnProperty(col)) {
table[row][col] = "-";
}
}
}
The reason why your code did not work is that by iterating over the rows, you do not get all the possible type properties, which becomes clear if you inspect your table variable: { a: {1: "1", 2: "0", 5: "1"}, b: {...}} (this is missing the 3 type property), so by calling Object.values(table[row]) later on, you get the following array for your cells: ["1", "0", "1"], but you do have 4 columns, so the "Type 5" result (1) gets shifted one column to the left.
Also, you need to be careful because your code is relying on the sorting that Object.values() produces, which means that if you want to change the order of your columns, your code would not work.

How do I make a JSON object produce HTML on the page

Here is my JSON
var gal = [
{
"folder":"nu_images",
"pic":"gd_42.jpg",
"boxclass":"pirobox_gall",
"alt":"Rand Poster 1",
"title":"Rand Poster 1",
"thfolder":"th",
"thumbpic":"th_gd_42.jpg"
},
{
"folder":"nu_images",
"pic":"gd_13.jpg",
"boxclass":"pirobox_gall",
"alt":"Explosive Pixel Design",
"title":"Explosive Pixel Design",
"thfolder":"th",
"thumbpic":"th_gd_13.jpg"
}
];
and here is my for loop
for (i = 0; i < gal.length; i++) {
document.getElementById("gallery").innerHTML = "" + "<img src=\"" + "http:\/\/galnova.com\/" + gal[i].folder + "\/" + "th\/" + gal[i].thumbpic + "\"" + "border=\"0\"" + "alt=\"" + gal[i].alt + "\"" + "title=\"" + gal[i].title + "\"\/>" + ""
};
I am trying to make my JSON show all of the objects in HTML one after the other. I can get it to show the first one or whatever number I put into the array but I don't know how to make it generate a list of them.
Here is a link to my jsfiddle. Any help you can offer would be greatly appreciated.
http://jsfiddle.net/o7cuxyhb/10/
It's being generated here <p id="gallery"></p> just not correctly.
You're overwriting your html with every loop iteration:
document.getElementById("gallery").innerHTML = ...
^---
Perhaps you want something more like
document.getElementById("gallery").innerHTML += ...
^---
which will concatenation the original html contents with your new stuff.
And technically, you shouldn't be doing this in a loop. Changing .innerHTML like that causes the document to be reflowed/re-rendered each time you change .innerHTML, which gets very expensive when you do it in a loop. You should be building your html as a plain string, THEN adding it to the dom.
e.g.
var str = '';
foreach(...) {
str += 'new html here';
}
document.getElementById("gallery").innerHTML += str;
for (i = 0; i < gal.length; i++) {
document.getElementById("gallery").innerHTML += "" + "<img src=\"" + "http:\/\/galnova.com\/" + gal[i].folder + "\/" + "th\/" + gal[i].thumbpic + "\"" + "border=\"0\"" + "alt=\"" + gal[i].alt + "\"" + "title=\"" + gal[i].title + "\"\/>" + "" };
Add a += instead of an = after innerHTML
Try this:
function displayJson(jsonArray){
var container = document.getElementById("gallery");
for (var i=0; i<jsonArray.length; i++){
var newElement = document.createElement("a").innerHTML = jsonToHtml(jsonArray[i])
container.appendChild(newElement);
}
}
function jsonToHtml(jsonObj){
//Define your dom object here
var el = document.createElement("a").innerHTML = '' // you code here
...
return el;
}
displayJson(gal);

Sort JSON data by Date/Time value

Hope someone could help with this small task. I have an array of text blocks that have a DateTime value assigned to them. I would like to publish those text blocks sorted by DateTime so that the latest updated item is always on top.
Here is the script:
function jsonCallBack(data) {
var strRows = "";
$.each(data.News, function(i, item) {
var htmlNewsBody = item["htmlNewsBody"];
var maxLength = 120
var trimmedString = htmlNewsBody.substr(0, maxLength);
trimmedString = trimmedString.substr( 0, Math.min( trimmedString.length,
trimmedString.lastIndexOf(" ") ) );
strRows += "<div id='nrNewsItem-" + i + "'>";
strRows += "<h3>" + item["txtTitle"] + "</h3>";
strRows += "<p>" + item["dtDateTime"] + "</p>";
strRows += "<p>" + trimmedString + "...</p>";
strRows += "</div>"
});
$("#printHere").html(strRows);
};
Also have a working jsFiddle with JSON data.
You can add a custom compare method:
function compare(a,b) {
if (a.dtDateTime < b.dtDateTime) {
return 1;
}
if (a.dtDateTime > b.dtDateTime) {
return -1;
}
return 0;
}
Then in your function:
function jsonCallBack(data) {
data.News.sort(compare);
....

Graph API - FB - Getting crazy already. :s - Getting profile pictures

I can get the profile pictures from this:
data": [
{
"id": "11111111111_22222222222",
"from": {
"name": "Some Name",
"category": "Non-profit organization",
"id": "11222131212211"
},
I'm doing like so:
$.each(json.data,function(i,fb){
html += "<img id=\"image"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
}
No problems.
However, later on the graph I have:
"id": "11111111111_2222222222",
"to": {
"data": [
{
"name": "Some Name",
"category": "Non-profit organization",
"id": "11222131212211"
And I need to grab this id but I've tried:
alert(fb.to.data.id); got nothing.
If I do: alert(fb.to) I got "undefined".
Has anyone had this sort of problems or similar. As you may notice I'm not at all versatle onto programing matters, however, I will do my best to solve this issue.
1) How can I display the profile image on the second case?
2) How can I say: use the fb.from.id only when the graph has that.
About 2), please note that if I comment the line:
//html += "<img id=\"image"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
no images will be show and all post information (except the profile picture) is displayed on the viewport.
If I deal only with the first part of this graph (the one with "from:") I get the picture for that post.
SO, the issue must be, indeed, on the second graph part. The one with the "to:" that I can't grab the ID.
I've tried, as well, to avoid rendering the image on the second case but, at least run the first one. No luck at all.
if (fb.from.id != undefined) {
//do something;
}
The second part of the graph still returns an error.
With all this mess, that I can re-arrange, can I please ask your help. :S
**
Update:
**
The js code:
function fbFetch(){
var url = "https://graph.facebook.com/125120007543580/feed&callback=?&limit=2";
var i = 0;
//Use jQuery getJSON method to fetch the data from the url and then create our unordered list with the relevant data.
$.getJSON(url,function(json){
var html = "<div id=\"faceWall\">";
//loop through and within data array's retrieve the message variable.
$.each(json.data,function(i,fb){
var idTotal = fb.id;
var ids = idTotal.split("_");
var href = "http://www.facebook.com/"+ids[0]+"/posts/"+ids[1];
var msg = fb.message;
//adicionado
if (msg == undefined) {
msg = 'Cick here to see the post title';
} else if (msg.length > 150) {
msg = msg.substr(0,200)+"...";
}
//ISSUE HERE. IF I COMMENT THIS LINE ALL GOES WELL BUT NO PROFILE PICTURES ARE DISPLAYED.
html += "<img id=\"imagem"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
html += "<div id=\"textoFaceWall\">";
html += "<p id=\"msg"+i+"\">";
//adicionado fb.name em vez de fb.from.name:
if (fb.name == undefined) {
html += "" + fb.from.name + " - " + msg + "</p>";
} else {
html += "" + fb.name + " - " + msg + "</p>";
}
html += "<p class=\"dataPostWall\" id=\"data"+i+"\">"+ dataFinal + "</p> ";
html += "</p>";
html += "</div>";
html += "<img class=\"linhaHomePageCanais\" src=\""+baseUrl+"/lib/img/linhaWall.png\" alt=\"linha wall\"/>";
});
html += "</div>";
$("#coluna2").append(html);
});
};
fbFetch();
And part of the graph:
({
"data": [
{
"id": "125120007543580_150880001634837",
"from": {
"name": "Some Name",
"category": "Non-profit organization",
"id": "125120007543580"
},
{
"id": "125120007543580_111122368963254",
"to": {
"data": [
{
"name": "Some Name",
"category": "Non-profit organization",
"id": "125120007543580"
}
]
},
I need to display the profile from fb.to.data.id,
I now notice, however, that data has [ instead of {, and that could mean that, in order to access id, I need to use another syntax perhaps?
Since the to parameters can holds more that one user, it's an array of objects. So you need to loop over that too:
if(fb.to) {
$.each(fb.to.data, function(j,to_user) {
// now you access it to_user.id
});
}
If you only want to show the first profile picture then use fb.to.data[0].id.
EDIT:
Okay, based on your comments and updated, here is your code with a working approach:
function fbFetch(){
var url = "https://graph.facebook.com/125120007543580/feed&callback=?&limit=2";
var i = 0;
//Use jQuery getJSON method to fetch the data from the url and then create our unordered list with the relevant data.
$.getJSON(url,function(json){
var html = "<div id=\"faceWall\">";
//loop through and within data array's retrieve the message variable.
$.each(json.data,function(i,fb){
var idTotal = fb.id;
var ids = idTotal.split("_");
var href = "http://www.facebook.com/"+ids[0]+"/posts/"+ids[1];
var msg = fb.message;
//adicionado
if (msg == undefined) {
msg = 'Cick here to see the post title';
} else if (msg.length > 150) {
msg = msg.substr(0,200)+"...";
}
//ISSUE HERE. IF I COMMENT THIS LINE ALL GOES WELL BUT NO PROFILE PICTURES ARE DISPLAYED.
if(fb.from)
html += "<img id=\"imagem"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
if(fb.to) {
$.each(fb.to.data, function(j,to_user) {
html += "<img id=\"imagem"+i+"-"+j+"\" src=\"http://graph.facebook.com/" + to_user.id + "/picture\"/>";
});
}
html += "<div id=\"textoFaceWall\">";
html += "<p id=\"msg"+i+"\">";
//adicionado fb.name em vez de fb.from.name:
if (fb.name == undefined) {
html += "" + fb.from.name + " - " + msg + "</p>";
} else {
html += "" + fb.name + " - " + msg + "</p>";
}
html += "<p class=\"dataPostWall\" id=\"data"+i+"\">"+ dataFinal + "</p> ";
html += "</p>";
html += "</div>";
html += "<img class=\"linhaHomePageCanais\" src=\""+baseUrl+"/lib/img/linhaWall.png\" alt=\"linha wall\"/>";
});
html += "</div>";
$("#coluna2").append(html);
});
};
fbFetch();
You may try this for PHP
$request_url = 'http://graph.facebook.com/redbull/picture?redirect=false';
$requests = file_get_contents($request_url);
$fb_response = json_decode($requests);
$imagen[]=$fb_response->data->url;
There you get the URL of the picture from the URL item in the JSON Graph api call.