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

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.

Related

Parsing and displaying JSON data

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.

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);

JsTree with JSON stuck on loading

I am using JSON to display a JsTree. The JSON is being built up as a string via a recursive function. Now I went through a few tests with smaller/less complicated trees and got it to work. I used JSONLint to check for valid JSON and eventually got the correct syntax. Now when I try and display the intended big tree its just stuck with the loading .gif (which used to be because the JSON was incorrect) but after checking it on JSONLint it was correct.
Any possible causes for this? I doubt the tree could be too big or anything.
Recursive Function:
public void getViewTree(ref string tree, Int32? id = null)
{
var topNodes = (from items in db.AssessmentViewItems
select items).Take(1);
#region getChildren via LINQ
if (id == null)
{
topNodes = from items in db.AssessmentViewItems
where items.ParentAssessmentViewItemID == null
&& items.AssessmentViewID == 17
select items;
}
else
{
topNodes = from items in db.AssessmentViewItems
where items.ParentAssessmentViewItemID == id
&& items.AssessmentViewID == 17
select items;
}
#endregion
int counter = 1;
int max = (int)topNodes.Count();
foreach (var node in topNodes)
{
if (node.ParentAssessmentViewItemID == null)
{
{\"id\":\"532topNode\",\"selected\":true},\"children\":[null,
tree += "{\"data\":\"" + node.Title.Trim().Replace("\"","").Replace("("," ").Replace(":"," ").Replace("-"," ").Replace("&","and").Replace("/"," ").Replace("\\"," ").Replace(","," ").Replace("•", " ") + "\",\"attr\":{\"id\":\"" + node.AssessmentViewItemID + "\", \"selected\":true}, \"children\":[";
getViewTree(ref tree, node.AssessmentViewItemID);
tree += "}]";
if (counter < max)
{
tree += "},";
}
}
else if (node.Type.Equals("Legal Topic"))
{
tree += "{\"data\":\"" + node.Title.Trim().Replace("\"", "").Replace("(", " ").Replace(":", " ").Replace("-", " ").Replace("&", "and").Replace("/", " ").Replace("\\", " ").Replace(",", " ").Replace("•", " ") + "\",\"attr\":{\"id\":\"" + node.AssessmentViewItemID + "\", \"selected\":true}";
if (counter < max)
{
tree += "},";
}
}
else
{
var topNodes1 = from items in db.AssessmentViewItems
where items.ParentAssessmentViewItemID == node.AssessmentViewItemID
&& items.AssessmentViewID == 17
select items;
if (topNodes1.Count() > 0)
{
tree += "{\"data\":\"" + node.Title.Trim().Replace("\"", "").Replace("(", " ").Replace(":", " ").Replace("-", " ").Replace("&", "and").Replace("/", " ").Replace("\\", " ").Replace(",", " ").Replace("•", " ") + "\",\"attr\":{\"id\":\"" + node.AssessmentViewItemID + "\", \"selected\":true}, \"children\":[";
}
else
{
tree += "{\"data\":\"" + node.Title.Trim().Replace("\"", "").Replace("(", " ").Replace(":", " ").Replace("-", " ").Replace("&", "and").Replace("/", " ").Replace("\\", " ").Replace(",", " ").Replace("•", " ") + "\",\"attr\":{\"id\":\"" + node.AssessmentViewItemID + "\", \"selected\":true}";
}
getViewTree(ref tree, node.AssessmentViewItemID);
if (topNodes1.Count() > 0)
{
tree += "}]";
}
if (counter < max)
{
tree += "}";
tree += ",";
}
}
counter++;
}
}
JS:
$(function () {
$("#demoTree").jstree({
"json_data": {
"data": treeModel
},
"plugins": ["themes", "json_data", "ui"],
});
});
Calling Recursive Function:
string tree = "[";
getViewTree(ref tree);
tree += "}]";
return View("About", "_Layout", tree);
After using Chrome Dev Tools, the error that I get from it:
Uncaught SyntaxError: Unexpected token ILLEGAL (program):54
Uncaught Neither data nor ajax settings supplied.
I did check it for syntax on JSONLint. Small tree is generated fine without those 2 errors
Problem got solved by using DevExpress tree. Exact same JSON string.

How to serialize HTML DOM to XML in IE 8?

Is there a way to do it(serialization of HTML DOM into XML) in IE 8 or any other older version of IE.
In firefox :
var xmlString = new XMLSerializer().serializeToString( doc );
does it.I haven't tried it, though.
XMLSerializer causes error in IE 8, that it is not defined.
var objSerializeDOM = {
//Variable to hold generated XML.
msg : "",
serializeDOM : function() {
dv = document.createElement('div'); // create dynamically div tag
dv.setAttribute('id', "lyr1"); // give id to it
dv.className = "top"; // set the style classname
// set the inner styling of the div tag
dv.style.position = "absolute";
// set the html content inside the div tag
dv.innerHTML = "<input type='button' value='Serialize' onClick='objSerializeDOM.createXML()'/>"
"<br>";
// finally add the div id to ur form
document.body.insertBefore(dv, document.body.firstChild);
},
/**
* XML creation takes place here.
*/
createXML : function() {
objSerializeDOM.msg += "";
objSerializeDOM.msg += "<?xml version='1.0' encoding='UTF-8'?>\n\n";
// Get all the forms in a document.
var forms = document.forms;
for ( var i = 0; i < forms.length; i++) {
// Get all the elements on per form basis.
elements = document.forms[i].elements;
objSerializeDOM.msg += "<FORM name=\"" + forms[i].name + "\" method=\""
+ forms[i].method + "\" action=\"" + forms[i].action + "\">\n\n";
for ( var j = 0; j < elements.length; j++) {
objSerializeDOM.msg += " <" + elements[j].tagName + " type=\""
+ elements[j].type + "\"" + " name=\""
+ elements[j].name + "\"" + " Value =\""
+ elements[j].value + "\" />\n";
}
alert(document.forms[i].elements[1].event);
}
objSerializeDOM.msg += "\n\n</FORM>\n\n";
alert(objSerializeDOM.msg);
objSerializeDOM.writeToFile(objSerializeDOM.msg);
},
/**
* Writes the msg to file at pre-specified location.
* #param msg
* the XML file created.
*/
writeToFile : function(msg) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fh = fso.CreateTextFile("c:\\myXML.xml", true);
fh.WriteLine(msg);
fh.Close();
}
};
objSerializeDOM.serializeDOM();
I wrote this JS, I run this javascript using GreaseMonkey4IE. This simply puts a button on every page of the domain you specify in GM4IE. On click of that button it will parse the HTML document and create an XML file. It will also display the same as an alert first and will save the XML in your local drive on path specified.
There a still many improvements I am planning to do, but yes it works and may be give you guys an idea.The program is self-explanatory, I hope.
please have a look here How to get Events associated with DOM elements?Thanks

Loop stopping when undefined

UPDATE 6:
Based on the console.log, I have noticed that some of the objects have:
thumbnail: Array[2]
Others have:
thumbnail: Object
and others don't have it at all.
So it seems that what #Felix Kling could be true.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%22http%3A%2F%2Ffeeds.bbci.co.uk%2Fnews%2Frss.xml%22&format=json&callback=cbfunc
if you can't access the link, try:
http://pastebin.com/T4GPQvtk
UPDATE 5:
I am still getting url as undefined with:
for (var i = 0; i < news.length; i++) {
news[i].thumbnail = ( $.isArray( news[i].thumbnail ) ) ? news[i].thumbnail : [news[i].thumbnail];
buildHTML.push( "<a href='" + news[i].thumbnail[0].url + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
}
UPDATE 4:
The following:
buildHTML.push( "<a href='" + news[i].thumbnail[0] ? news[i].thumbnail[0].url : $.isArray( news[i].thumbnail ) + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
gives me:
Uncaught TypeError: Cannot read property 'url' of undefined
UPDATE 3:
The following does not seem to work either:
buildHTML.push( "<a href='" + news[i].thumbnail[0] ? news[i].thumbnail[0].url : news[i].thumbnail.url + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
The error I get is:
Uncaught TypeError: Cannot read property 'url' of undefined
UPDATE 2:
The following does not seem to work:
buildHTML.push( "<a href='" + news[i].thumbnail=$.isArray(news[i].thumbnail)?news[i].thumbnail:[news[i].thumbnail] + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
The error I get is:
Uncaught ReferenceError: Invalid left-hand side in assignment
$.ajax.successyql_news_widget.js:25
bjquery-1.4.2.min.js:124
c.extend.ajax.Ajquery-1.4.2.min.js:125
(anonymous function)yql:1
UPDATE 1:
The problem happens, when I add the image to push as follows:
buildHTML.push( "<img src='" + news[i].thumbnail[0].url + "' /><a href='" + news[i].link + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
ORIGINAL QUESTION:
From the following url:
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%22http%3A%2F%2Ffeeds.bbci.co.uk%2Fnews%2Frss.xml%22&format=json&callback=cbfunc
I am trying to capture the data via a look like this:
function get_news() {
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%22http%3A%2F%2Ffeeds.bbci.co.uk%2Fnews%2Frss.xml%22&format=json&callback=cbfunc&rand=" + Math.random(),
type: 'GET',
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'cbfunc',
error: function(xhr, status, error) {
alert(xhr.responseText);
},
success: function(data) {
var buildHTML = [];
var news = data.query.results.rss.channel.item;
for (var i = 0; i < news.length; i++) {
buildHTML.push( "<a href='" + news[i].link + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
}
$('.portlet-content').empty().append(buildHTML.join("<br /><br />"))
}
});
}
This works fine as long as the thumbnail section looks like this:
"thumbnail": [
{
"height": "49",
"url": "http://news.bbcimg.co.uk/media/images/48915000/jpg/_48915868_48915872.jpg",
"width": "66"
}
{
"height": "81",
"url": "http://news.bbcimg.co.uk/media/images/52468000/jpg/_52468689_48915872.jpg",
"width": "144"
}
]
However, when the thumbnail section looks like this:
"thumbnail": {
"height": "81",
"url": "http://news.bbcimg.co.uk/media/images/53705000/jpg/_53705922_012314461-1.jpg",
"width": "144"
}
I get an error "undefined", the loop stops and I get nothing on the screen.
How do I ignore those, and continue the script without it stopping on the error?
You may create an array if the json matches the 2nd example(isn't an array yet):
news[i].thumbnail=($.isArray(news[i].thumbnail))
? news[i].thumbnail
: [news[i].thumbnail];
Based on your comments, you seem to want this:
for (var i = 0; i < news.length; i++) {
var item = news[i];
if($.isArray(item.thumbnail)) {
var size = +item.thumbnail[0].width * +item.thumbnail[0].height,
selected = 0;
for(var j = 1, jl = item.thumbnail.length; j < jl; j++) {
var t_size = +item.thumbnail[j].width * +item.thumbnail[j].height;
if(t_size < size) {
size = t_size;
selected = j;
}
}
buildHMTL.push("<img src='" + news[i].thumbnail[selected].url + "' />");
}
buildHTML.push( "<a href='" + item.link + "' target='_blank'>" + item.title + "</a><br />" + item.pubDate );
}
Add [] brackets to cast "thumbnail" from object to array.
"thumbnail": [ {
"height": "81",
"url": "http://news.bbcimg.co.uk/media/images/53705000/jpg/_53705922_012314461-1.jpg",
"width": "144"
}]
will work
You can use a Try catch or a simple IF before the code to check to see if the code is in the format you want before attempting to manipulate it. The issue seems to be that if your thumbnails 'array' is only one object its not sent as an array. A simple if check could stop this issue your having.
you can use a conditional operator which would go something like this:
buildHTML.push( "<img src='" + news[i].thumbnail[0] ? news[i].thumbnail[0].url : news[i].thumbnail.url + "' /><a href='" + news[i].link + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
UPDATE
this conditional expression will find the URL or it will just return "". I didn't see that some items have no URL which is why my first suggestion didn't work. Use this expression for getting your url
news[i].thumbnail ? news[i].thumbnail[0] ? news[i].thumbnail[0].url : news[i].thumbnail.url : ''