Ajax asynchronous response not loading into div - javascript

Here is what bothering me. My code is running on document.ready. I need the request to be asynchronous, meaning async: true
for (var i = 0; i < totalGraphs; i++) {
var kpiId = kpiIds[i];
jQuery.ajax({
type: 'POST',
url: graphUrl,
data: "kpiId="+kpiId+"&divId="+(i+1),
async: true, //if false things are working fine
cache:false,
success: function(response){
document.getDocumentById("graph" + (i + 1)).innerHTML("hello");
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
}
});
}
This request does not put hello in my graphX divs, but whenever i put async: false things are working fine. I really need the request to be asynchronous.
Thanks in advance for any help.

Try this...
for (var i = 0; i < totalGraphs; i++){
(function ajaxCall(index) {
var kpiId = kpiIds[index];
jQuery.ajax({
type: "POST",
url: graphUrl,
data: {
kpiId : kpiId,
divId : index + 1
},
async: true, //if false things are working fine
cache: false,
success: function(response) {
document.getDocumentById("graph" + (index + 1)).innerHTML("hello");
},
error: function(XMLHttpRequest,textStatus,errorThrown) {}
});
})(i);
}
I've wrapped the ajax call in an anonymous function so that the value of i will never change, relative to the ajax call.

I'm guessing the i count is getting mixed up in your loop when success is returned. success will return after the loop has run through and thus this will give an unexpected result.
Can you return the i value that went sent in data in your response then use this in your getDocumentById method? I'm guessing this would fix your issue.
New code to try:
for(var i=0;i<totalGraphs;i++){
jQuery.ajax({
type: 'POST',
url: graphUrl,
data: { kpiId: kpiIds[i], divId: (i+1) },
async: true, //if false things are working fine
cache:false,
success: function(response){
document.getDocumentById("graph" + response.count).innerHTML("hello");
},
error:function(XMLHttpRequest,textStatus,errorThrown){}
});
}

First of all, you are running an ajax call inside a loop. This will be okay if you've turned off the async. But since you've turned on the async, the loop doesn't wait for the ajax to finish its work.
The best thing to do would be to get the values to a global variable using the inner loop ajax and then use the variable to draw the graph later.

Related

How to get multiple ajax request with promises

I'm trying to get a single image from each ajax request and append it to a li box container, the first ajax returns a list of 20 objects, with name and a url
$.ajax({
url: "http://pokeapi.co/api/v2/pokemon/",
dataType: "json",
method: "GET",
cache: false,
success: function(data) {
for (var i = 0; i<data.results.length ;i++){
$("#root ul").append('<li class="box"></li>');
$("li").eq(i).append('<h2>' + data.results[i].name +'</h2>');
}
setPkmImage(data.results);
console.log(data);
},
error: function(data) {
console.log("Error");
}
});
The problem starts when I try to make a call for each of those objects to request an image, it works with the async: false, but i don't want to do it that way since it takes a lot of time to load all the images.
function setPkmImage(res){
for (var i = 0; i < res.length; i++) {
var promise = $.ajax({
url: res[i].url,
dataType: "json",
method: "GET",
cache: false,
//async: false,
promise.done( function(data) {
console.log(data);
$("#root ul");
$("li").eq(i).append('<img src="' + data.sprites.front_default+ '"/>');
});
promise.fail( function(data) {
console.log("Error");
});
});
}
}
I'm trying to use promises but I don't know exactly how to structure it
Two major problems, one is syntax and the other is you need a closure loop
First the $.ajax is not closed properly.
Should look more like:
var promise = $.ajax({
url: res[i].url,
dataType: "json",
method: "GET",
cache: false
});
promise.done(...
promise.fail(...
As for the closure loop, i won't be what you want it to be inside the ajax callbacks because the for loop will have been completed before the data for requests is returned. Thus i will be at it's maximum by then
Try changing the for loop to $.each which creates a closure
$.each(res, function(i, item){
var promise = $.ajax({
url: item.url,
dataType: "json",
method: "GET",
cache: false
});
promise.done(...
promise.fail(...
})
I usually use the next solution. After first request is done, I've insert to dom img with url (url is come from request) and browser will load images automatically.

How can I check if there are changes in my database

What I want is a technique to refresh my div if there are changes in my database. Here is the point,
What i want: How can i condition to know if the first value from my database is lesser than the upcomming value.
In my situation, i put my ajax function to be run every 5secs here is it:
lastcountQueue is declared as global in javascript
function check_getqueue() {
$.ajax({
url: siteurl+"sec_myclinic/checkingUpdates/"+clinicID+"/"+userID,
type: "POST",
dataType: "JSON",
success: function(data) {
lastcountQueue = data[0]['count'];
}
});
}
Q:where would i put the condition something if lastcountQueue < data[0]['count]; condition means something if the data is lesser than lastcountQueue it means there was a change in my database portion.
Another Clear Situation for my question:
I want to make a function like these: the ajax will run every 5 seconds where it query a value to count my no. of queues in database. If my first query is giving me 5 value, and the second is giving me again another 5, then there must be nothing change happens, then if my third value gives me 4, where it is not equal to the last query, then i would do something
Probably something like this:
function check_getqueue() {
$.ajax({
url: siteurl+"sec_myclinic/checkingUpdates/"+clinicID+"/"+userID,
type: "POST",
dataType: "JSON",
success: function(data) {
var tmpCountQ = data[0]['count'];
if (tmpCountQ < lastcountQueue) {
// Process the change
}
lastcountQueue = tmpCountQ;
}
});
}
Here is the updated answer:
function check_getqueue() {
$.ajax({
url: siteurl + "sec_myclinic/checkingUpdates/" + clinicID + "/" + userID,
type: "POST",
dataType: "JSON",
success: function(data) {
if (data[0]['count'] != lastcountQueue) {
//Your logic here
lastcountQueue = data[0]['count'];
}
}
});
}

jQuery .ajax Call Returns JSON ParseError Even Thought JSON Appears to be Correct?

I'm getting a ParseError even though my JSON validates on jsonlint.com.
Here is the jQuery code:
$.ajax({
url: path,
type: 'GET',
data: {},
cache: false,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
var a = 'breakpoint here doesn't activate';
},
error: function (x, y, z) {
var b = 'code execution stops at a breakpoint here.';
}
});
Here is the PHP code that is being called:
function getAllAnswersToHitViaAjax($theJobName) {
$testData[0] = 'testing123';
$encodedData = json_encode($testData);
echo $encodedData;
return;
}
This comes back to a breakpoint set in the error: function of my .ajax call. Parameter Y is set to "parseerror", and x.responseText =
["testing123"]
I've been looking into this for hours so far. I've looked at many relevant StackOverflow posts, but none have solutions that work in this case.
How can I get a success response from this .ajax call?
Thanks very much in advance to all for any info.
There's nothing visibly wrong with your code, and it works fine when I try it on my local machine. However, your comment above is a big clue:
I just looked at the z param in the Safari console, and found this:"undefined is not a function (evaluating 'JSON.parse(a+"")')" How could that be happening?
It could happen if some code somewhere uses "JSON" as a global variable name, hiding the built-in window.JSON object.
Check for Notice or Warning in your php code, if their is any then remove that and then try. Hop this will help you.
JavaScript allows either single or double quotes for strings, but JSON only allows double quotes. See http://www.json.org/
See also jQuery.parseJSON single quote vs double quote
Just Use
function getAllAnswersToHitViaAjax($theJobName) {
$testData[0] = 'testing123';
echo json_encode($testData);
}
Then in your AJAX you can do
$.ajax({
url: path,
type: 'GET',
dataType: 'json'
success: function(data){
for (var i = 0; i < data.length; i++) {
//DO YOUR STUFF
}
}
});
Please use
$.ajax({
url: path,
type: 'GET',
cache: false,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
var a = 'breakpoint here doesn\'t activate';
},
error: function (x, y, z) {
var b = 'code execution stops at a breakpoint here.';
}
});
and in your PHP CODE Paste this code.
function getAllAnswersToHitViaAjax($theJobName) {
$testData[0] = 'testing123';
$encodedData = $testData;
echo json_encode($encodedData);
exit;
}
May be after digging more in your code I assume that in your PHP code you were not passing data properly. Please use exit or die method to pass data back to ajax. Please check.
Try with the below code,
function getAllAnswersToHitViaAjax($theJobName) {
$testData[0] = 'testing123';
echo json_encode($testData);
die();
}
$.ajax({
url: path,
type: 'GET',
dataType: 'json'
success: function(data){
console.log(data);
var result = JSON.parse(data);
console.log(result);
}
});

Stacking multiple AJAX requests on success (jQuery)

I'm just testing a local application and wanted to make something like this:
Click button, that's easy.
Perform AJAX request and create a database table.
Once the table is created, perform another series of AJAX requests and populate the table according to some parameters gotten from a series of select boxes.
"Animate" the whole thing using a progress bar.
Surprisingly, everything is working fine (apart the last point), but I'm getting some troubles.
The table gets created and populated but, for some reasons, the very last AJAX requests doesn't fire correctly, since it's not passing a parameter correctly.
My ajax requests are ALL asyncronous, if I set them syncronous the whole thing will freeze, but all the requests are executed correctly, even the very last one.
For instance, let's say that I don't want to use asyncronous requests in order to DON'T freeze the page and be able to show a progress bar.
The questions are the following:
Is it possible to call the same script twice?
Is there an efficient way to avoid ajax requests executing before other ajax requests?
After reading a whole bunch of topics here in stackoverflow, I edited my code and tried to:
use jQuery.AJAX prototype instead of jQuery.POST
Set everything asyncronously, in order to don't freeze the page and be able to handle a progress bar
perform the very next AJAX request into the "success" callback of the parent AJAX request.
At this point, I still have another question:
By stacking AJAX requests, is it actually TRUE that everything executed into the "success" callback will be executed AFTER the ajax requests has completed?
This is what I'm performing:
$.ajax({
type: "POST",
url: '../libs/php libraries/agenda.php',
data: {'action':'create>agenda', 'sqlname': createInfo},
processData: true,
dataType: "json",
timeout: 60000,
async: true,
success: function(res) {
$('#popup_content').append(res.log);
var dateList = new Array();
var dateObj = new Date();
var m = dateObj.getMonth();
var Y = dateObj.getFullYear();
for (var i = 1; i <= 31; i++) {
dateList.push(i+"/"+m+"/"+Y);
}
for (var i = 0; i < dateList.length; i++) {
var rs = false;
$.ajax({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'validate>date', 'date': dateList[i]},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(x) {
$('#popup_content').append(x.log);
if (x.res == 'true') {
rs = dateList[i];
}
if (rs != false) {
$.ajax({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'create>day', 'date': rs, 'sqltable': createInfo},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(newResult) {
console.log(newResult.res);
$('#popup_content').append(newResult.log);
}
});
}
}
});
}
}
});
the first AJAX request executes correctly, the second one does too, but in the third one (the one with data: {'action':'create>day', 'date': rs, 'sqltable': createInfo}) is getting fired but is missing the parameter rs defined above.
Also, to be clearer, rs is a temporary variable I've defined when I was trying to make the requests outside the "success" callback and when using $.when and $.done, in this case the variable rs is useless, but It won't change anything.
Again, as said above, the whole thing works using a syncronous request, but doesn't by using an asyncronous one.
Moreover, I'm just going to use this script locally, so delays or every problematic related to delays caused by servers and client are not important.
Is there any reason for the last request to don't work with an asyncronous request? if so is there a valuable solution for this case? I've also checked the topics about the queue, but it didn't solve my problem either. For some reasons, asyncronously, the last AJAX requests get just partially fired, since the variable rs is not getting passed correctly.
One solution is to use queue() function. This way you can execute as many functions as you want
var ajaxQueue = $({});
$.ajaxQueue = function(date, ajaxOpts) {
// queue the method. a second call wont execute until this dequeues
ajaxQueue.queue(function(next) {
// for this example I serialize params, but you can save them in several variables
// and concat into ajaxOpts.data
var params = method_that_get_params_and_serialize_them();
ajaxOpts.data = params;
ajaxOpts.complete = function() {
next();
};
$.ajax(ajaxOpts);
});
};
Then your functions have no need of shared vars, with the concurrency conflicts that it causes.
It should be like this:
$.ajax({
type: "POST",
url: '../libs/php libraries/agenda.php',
data: {'action':'create>agenda', 'sqlname': createInfo},
processData: true,
dataType: "json",
timeout: 60000,
async: true,
success: function(res) {
$('#popup_content').append(res.log);
var dateList = new Array();
var dateObj = new Date();
var m = dateObj.getMonth();
var Y = dateObj.getFullYear();
for (var i = 1; i <= 31; i++) {
dateList.push(i+"/"+m+"/"+Y);
}
for (var i = 0; i < dateList.length; i++) {
processDate(dateList[i]);
}
}
});
function processDate(date){
$.ajaxQueue({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'validate>date', 'date': date},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(x) {
$('#popup_content').append(x.log);
if (x.res == 'true') {
$.ajax({
type: 'POST',
url: '../libs/php libraries/agenda.php',
data: {'action':'create>day', 'date': date, 'sqltable': createInfo},
processData: true,
timeout: 60000,
async: true,
dataType: "json",
success: function(newResult) {
console.log(newResult.res);
$('#popup_content').append(newResult.log);
}
});
}
}
});
};
}

backbone javascript setTimeOut method

im have a problem with method setTimeOut that call the function self and set a delay, the function should be called again and again after every request is done but it only runs once. It works without using backbone.js tho, don't know it doesnt work after integration with backbone.js. Any help is appreciated!
So this is a function in client that runs a GET request gets data from server, the request runs in a time interval(decided in the server), as soon as a data comes in, client gets it and the request runs again after.
getRequest:function() {
var XHR = $.ajax({
url: '/nextdocument',
type: 'GET',
async: true,
cache: false,
timeout: 11000,
success:function(data) {
var name = data.description;
var price = data.price;
console.log("read--> " + name + price);
setTimeout("this.getRequest", 1000);
if (data.ok == "true") {
data["ok"] = data.ok;
$.ajax(
{
url: "/customerdone",
data: JSON.stringify(data),
processData: false,
type: 'POST',
contentType: 'application/json'
}
)
}else{
//no document if no read in
console.log("error--> " + data.errorMessage)
}
}
})
return XHR;
}
The problem is that you're using "this" in your setTimeout call. You can't do this because "this" will be the global object when the timer executes the function you're trying to reference.
like others have suggested, you need to pass an actual function to your timer, not a string. then you can reference whatever function from whatever object you want.
probably, the function getRequest isn't being called. This is, as far as I think, because you are sending a string -- "this.getRequest" to the setTimeout function. As a rule of thumb, never pass string to this, pass functions. Although, it might be perfectly ok in some situations (i'd never recommend it anyway), here 'this' might be causing trouble. Use something like this:
getRequest:function() {
var fn = arguments.callee;
var XHR = $.ajax({
url: '/nextdocument',
type: 'GET',
async: true,
cache: false,
timeout: 11000,
success:function(data) {
var name = data.description;
var price = data.price;
console.log("read--> " + name + price);
setTimeout(fn, 1000);
if (data.ok == "true") {
data["ok"] = data.ok;
$.ajax(
{
url: "/customerdone",
data: JSON.stringify(data),
processData: false,
type: 'POST',
contentType: 'application/json'
}
)
}else{
//no document if no read in
console.log("error--> " + data.errorMessage)
}
}
})
return XHR;
}

Categories