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.
Related
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;
});
}
I'm having trouble getting my information into an array in an ajax call, if I alert the information right after I insert it into the array it works fine, but if I do it at the end it alerts unidentified. I made sure that books is declared outside so it doesn't interfere.
var books = [];
$.ajax({
url: 'getFolderContents.php',
dataType: 'json',
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
},
error: function()
{
alert("error");
}
});
alert(books[0]);
Your
alert(books[0]);
will be executed while the Ajax call is running and therefore will not have any elements at this point of execution yet. Ajax is asynchronous - while you are doing a request to your PHP script your script continues execution.
Put all actions with books in your success function.
Another hint: As of jQuery version 1.8 you cannot longer use the parameter async: false to create a synchronous "A"jax call. You have to use the callback functions. Have a look at the docs for $.ajax
Your array hasn't lost any data; the data hasn't been put in there yet. The 'A' stands for "asynchronous", meaning your success callback hasn't run yet at the time you call the alert.
Put the alert inside your callback instead:
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
alert(books[0]);
},
Your alert is executing before the success function is called. Perhaps seeing the same code using a promise will make things clearer.
$.ajax( url: 'getFolderContents.php', dataType: "json" )
//the then function's first argument is the success handler
.then(function( data ) {
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
alert(books[0]
});
});
I always feel this syntax makes async stuff make more sense. Otherwise this code functions exactly like Blazemonger's correct answer.
Your AJAX call is asynchronous, that's why it is undefined.
The alert at the end happens before the ajax success callback, because ajax is asynchronous.
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");
}
I'm using jqgrid and am trying to request data from a webservice, parse it, and update a grid cell with the value. I expected to be able to do this with a custom formatter but I haven't been able to connect the dots on the asynchronous part of this function.
I've also ready that it may be wiser to use the gridLoaded { } call for this type of feature but in my mind the code I have below should work...
The formatter function gets called, make the async query which when completed fires the callback function which in turn updates the grid cell.
Any suggestions on what I may be missing would be greatly appreciated!
Thanks!
function recentPostsFormatter(cellValue, options, jsonVal) {
var encodedUrl = jsonVal.urlId;
var globalHTML = "";
var wsquery = 'webservice query goes here';
$.getJSON(wsquery, function (result) {
var html = "";
for (var i = 0; i < result.response.docs.length; i++) {
html += "<b>" + result.response.docs[i].title + "</b><br>" + result.response.docs[i].blogLink + ", " + result.response.docs[i].author + "<br>";
}
$("#blogListTable").jqGrid('setCell', object.rowId, 'recentPosts', html);
});
}
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.