getJSON not fetching data - javascript

My code below is not fetching data from data.js
The page works fine when the JSON data is hard coded into the page.
<head>
<title>Test Page</title>
<script>
function jsontest() {
var text;
$.getJSON("data.js", function(result) {
text = result;
});
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
}
</script>
</head>
<body onload="jsontest();">
<h1>Testing Page</h1>
<p id="content"></p>
</body>
My data looks like this
{"name":"John Johnson","street":"Oslo West 16","phone":"555 1234567"}
Am I making a simple nooby mistake?

The first thing I notice is that you're using getJSON in sync mode. This won't work since it's executed asynchronous. You need to place your logic inside finish handler
function jsontest() {
var text;
$.getJSON("data.js", function(result) {
text = result;
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
});
}
In your code, by the time you do
var obj = JSON.parse(text);
method getJSon didn't return yet so text contains the default value. It sends the request to the server and continue method flow without waiting for the result.
That's what the handler is for: to put logic that needs to be executed when request is complete.

$.getJSON is an async call - so when you try and run JSON.parse outside the callback, it won't work since the call is still in progress. Move your code to the callback and you'll be good:
function jsontest() {
$.getJSON("data.js", function(result) {
var text = result;
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
});
//Anything after the `getJSON` call is executed immediately.
//$.getJSON is still in progress when these lines are executing
}

Javascript is single-threaded and non-blocking, as a result, while the ajax call is being executed the program counter will continue. Thus will be parsing something which is undefined.
If you put the code beneath the ajax callback inside it, it will work just fine.

You have to put your code inside the callback, or you wont have the text var populated:
function jsontest() {
var text;
$.getJSON("data.js", function(result) {
text = result;
var obj = JSON.parse(text);
document.getElementById("content").innerHTML =
obj.name + "<br>" +
obj.street + "<br>" +
obj.phone;
});
}

Related

Nested JSON fetch using jQuery

I am trying to create an RSS Feed kind of Message display from Yammer.
<script type="text/javascript">
var cleanit = null;
$(document).ready(function(){ cleanit = setInterval('callYammer()', 50);});
function callYammer(){
clearInterval(cleanit);
$.getJSON("./yammer.feed?request=messages",function(json) {
var objYammer = $("#yammerFeed");
objYammer.html('');
$.each(json.messages, function(i, m) {
if(!m.replied_to_id && m.body.plain){
var data = "<li>" + m.body.plain;
$.getJSON("./yammer.feed?request=users&userid="+m.sender_id,function(jsonUser) {
//alert(jsonUser.full_name);
data = data + " - "+jsonUser.full_name;
});
data = data + "</li>";
objYammer.append(data);
}
});
});
return false;
}
</script>
I want to display Message along with it's Username.
But in the end, from firebug debugger, what I see is the inner JSON data is not getting appended as I expected.
Though the calls are hitting and data is coming from the call, the
data = " - "+jsonUser.full_name;
is getting executed after all JSON calls for Users.
How do I append Username from inner JSON call to main JSON data?
You call the lines
data = data + "</li>";
objYammer.append(data);
in the code following your inner getJSON AJAX call, but that probably results in these lines being executed before the AJAX request has finished. Put the code INTO the inner AJAX success function to make sure it is fired only after the result is available.
function callYammer(){
clearInterval(cleanit);
$.getJSON("./yammer.feed?request=messages",function(json) {
var objYammer = $("#yammerFeed");
objYammer.html('');
$.each(json.messages, function(i, m) {
if(!m.replied_to_id && m.body.plain){
var data = "<li>" + m.body.plain;
$.getJSON("./yammer.feed?request=users&userid="+m.sender_id,function(jsonUser) {
console.log('1:'+jsonUser.full_name);
data += " - "+jsonUser.full_name + "</li>";
objYammer.append(data);
console.log('2:'+data);
});
}
});
});
Edit:
Just added the console.log() statements. What do they return?

Can't set new value for variable

I'm possibly missing something that is very obvious, but I'm not getting nowhere with this problem.
I'm simple trying to set a value of a variable after getting the value from a json feed.
I'm using jquery to get a jsonp feed and then store the value in a variable that I can use later, but its not working and the value doesn't get stored. If I console.log the value it returns it.
jQuery(document).ready(function($){
serverip = "<?php echo $_SERVER['SERVER_ADDR']; ?>";
stream_domain = "";
$.ajax({url: 'http://load.cache.is/inspired.php?ip=' + serverip, dataType:'jsonp',
success: function(data){
$.each(data, function(key, val) {
if (key == serverip){
stream_domain = val;
console.log("val: " + val);
}
});
}
});
console.log(stream_domain);
});
Here is the same code on jsfiddle.net
You are making an asynchronous request. So your code which appends the HTML execute before the success does which assigns the variable.
The code following the ajax request executes immidiatly after the request is made.
So if you require the response data then you should move your append code to be executed from the success method similar to this:
if (key == serverip){
stream_domain = val;
console.log("val: " + val);
$("<span>" + val + "</span>").appendTo(".json");
$("<span>" + stream_domain + "</span>").appendTo(".variable");
}
DEMO
The ajax call is asynchronous, so the timeline of the events is :
make ajax call
console.log
ajax call success, variable assign
Wait for the success event before using the variable. Here is your updated jsFiddle where I've added a function called in the success callback function:
function continueWorking(){
console.log(stream_domain);
$("<span>" + stream_domain + "</span>").appendTo(".variable");
}

put $.getJSON(url, function(data) in a loop but yield wrong result

I run several calls to the Instagram API by using a loop but it yields weird result that I couldn't understand.
for(var i = 0; i < tags.length; i++){
document.write('search: ' + i + 'round');
document.write(tags[i] + ' ');
document.write('<hr />');
var url = 'https://api.instagram.com/v1/tags/'+ tags[i] +'/media/recent?&client_id=5a7b13571ced47418dd539e6fc97a67f&count='+count+'&callback=?';
$.getJSON(url, function(data) {
console.log(data.data.length);
if(data.data.length === 0){
//$('ul.images').append('<li>No results</li>');
} else {
$.each(data.data, function(index, value){
//console.log(value);
var imgUrl = value.images.low_resolution.url,
imgUser = value.user.username,
imgLink = value.link;
it.push(imgLink);
document.write(value.link + '<br />');
//$('ul.images').append('<li><img src="'+imgUrl+'"/></li>');
});
}
document.write('---------------------' + '<br />');
});
}
When I search three tags, cat, dog, pig, the result is:
search: 0roundcat
search: 1rounddog
search: 2roundpig
5 instagram image links
---------------------
5 instagram image links
---------------------
5 instagram image links
---------------------
So it seems the it first loop the three document.write() statement and then getting into $.getJSON() statement.
Any thoughts?
If your question is why the "i + round + tag" output comes before the output with the links, that is because getJSON() is asynchronous, i.e. it starts a request and returns immediately.
Then, after the for loop is finished, the execution has returned to the event loop and the results of the asynchronous requests have arrived, they are printed in the order that they arrived.
There are several ways to get around this, one would be something like this:
var tags = ['cat','dog','pig'];
function start_next_request() {
var tag = tags.shift();
var url = ...
$.getJSON(url, function (data) {
...
start_next_request();
}
}
start_next_request();

js function calling another js function and returning a value problem

i have this JS function:
function ax_get_new_msg_cnt()
{ var mTimer;
var last_msg_id;
mTimer = setTimeout('ax_get_new_msg_cnt();',30000);
$.getJSON('/apps_dev.php/profile/newMessageCheck', function(data)
{
$('#newMessageDiv').text("You have " + data.msg_cnt + " new ");
last_msg_id = data.msg_id;
});
return last_msg_id;
}
then i have the js function where i call ax_get_new_msg_cnt():
function ax_get_new_msg_details()
{
var mTimer;
mTimer = setTimeout('ax_get_new_msg_details();',30000);
$.getJSON('/apps_dev.php/messagebox/newMessageDetails', function(data)
{
var str='<tr>';
str += "<td class='td_show_contact_item' align='left' id='td_date'>"+data.td_date+'</td>';
str += "<td align='left' id='td_subject'><a href='#' style='color:#ff0000 !important' class='spn_small_red_rbc'>"+data.td_subject+"</a></td>";
str += "<td class='td_show_contact_item' align='left' id='td_from'>"+data.td_from +"</td>";
//str += "<td id='block_url'>"+data.block_url+"</td>";
str +='<tr>';
var tbl = $('#td_date').parents('table');
var msg_id = ax_get_new_msg_cnt();
console.log(msg_id);
if (msg_id == data.td_id)
{
}
else
{
$(tbl).append(str);
}
});
}
in the above function i get msg_id as undefined...
can i do it the way i have it or is there another way please?
only if msg_id != data.td_id i want to do the append
thank you
You need to understand the asynchronous way of programming.
In your first method, when it gets called it starts an async JSON request to the webserver, which will return later in time, but your $.getJSON call return immediately, so your last_msg_id variable will be untouched and this untouched (undefined) variable will be returned by ax_get_new_msg_cnt function.
Later when the webserver returned with the answer and the answer is read by your browser it passes back to your callback function which sets the last_msg_id.
You can write console.log debug messages to see the timings:
if you insert a console.log('JSON start'); to your ax_get_new_msg_details method before the $.getJSON call
then one console.log('Response arrived'); to inside the function(data) part
and an another one right before the end with console.log('JSON request sent');
then, you'll probably see the way of executing.
What ever you want to do with msg_id you need to do it in $.getJSON callback function. You can not return it. The Ajax call is asyncron, so you have to wait till it is finished to get the value.
Because the $.getJSON() method is asynchronous, your ax_get_new_msg_cnt() function will return before the data is received, leaving last_msg_id as undefined.
Moreover, I think that the URL parameter for $.getJSON() should point to a file, not to a folder.
Note: you could improve your code by using the $.ajaxSetup method to set a default timeout for all your jQuery ajax requests.

jquery control execution of the callback functions

Function socialbookmarksTableData(data) is called by another function to generate the content of a table -- data is a JSON object. Inside the function i call 2 other functions that use getJSON and POST (with json as a return object) to get some data. The problem is: though the functions execute correctly i get undefined value for the 2 variables (bookmarkingSites, bookmarkCategories). Help with a solution please.
function socialbookmarksGetBookmarkCategories(bookmarkID)
{
var toReturn = '';
$.post("php/socialbookmark-get-bookmark-categories.php",{
bookmarkID: bookmarkID
},function(data){
$.each(data,function(i,categID){
toReturn += '<option value ="' + data[i].categID + '">' + data[i].categName + '</option>';
})
return toReturn;
},"JSON");
}
function socialbookmarksGetBookmarkSites()
{
var bookmarkingSites = '';
$.getJSON("php/socialbookmark-get-bookmarking-sites.php",function(bookmarks){
for(var i = 0; i < bookmarks.length; i++){
//alert( bookmarks[i].id);
bookmarkingSites += '<option value = "' + bookmarks[i].id + '">' + bookmarks[i].title + '</option>';
}
return bookmarkingSites;
});
}
function socialbookmarksTableData(data)
{
var toAppend = '';
var bookmarkingSites = socialbookmarksGetBookmarkSites();
$.each(data.results, function(i, id){
var bookmarkCategories = socialbookmarksGetBookmarkCategories(data.results[i].bookmarkID);
//rest of the code is not important
});
$("#searchTable tbody").append(toAppend);
}
You return the variables from the callback functions, not the functions that you actually call. After the callback functions are called control is returned to the functions which have no return statements, so they 'return' undefined by default. You need to return values from socialbookmarksGetBookmarkCategories and socialbookmarksGetBookmarkSites not just from callback functions within them.
You need to execute the code in your socialbookmarksTableData function as a response to the $.getJSON call. The problem is that you are returning right away, but the JSON callback hasn't yet fired.

Categories

Resources