Loop in ajax, ordering function executions - javascript

I want to use jquery for checking sites servers one by one and if the server is ok start grabbing pages.
But in the following code, the loop execute at the first and 2 message appears at the first lines:
start analyzing site 1
start analyzing site 2
start grabbing site 1
start grabbing site 2
...
How I can change this to:
start analyzing site 1
start grabbing site 1
...
start analyzing site 2
start grabbing site 1
...
I am new in Jquery, but I have read about promise and deferrals but could not write the correct code.
I tested this code by async:false. It solves the problem, But I don't want to use this approach (You know the reason).
new_links_arr() = array('site1', 'site2');
function check_server(response) {
var new_links_c = new_links_arr.length;
for (var n = 0; n < new_links_c; n++) {
var this_link = new_links_arr[n];
if (this_link.length > 5) {
$("#responds").append("<hr/> start analyzing site: " + this_link + "");
var myData = 'mod=chk_srv&url=' + encodeURIComponent(this_link) + '&mk_rds_dir=1';
$.ajax({
type: "GET",
url: my_url,
dataType: "json",
data: myData,
cache: false,
success: grab_site,
error: end_error
});
}
}
}
function grab_site(response) {
$("#responds").append(" " + response.the_msg + " ");
var status = response.status;
if (status == 1) {
$("#responds").append(" start grabbing site ");
var myData = 'mod=chk_home&url=' + encodeURIComponent(response.url);
$("#Loding_info").html("Get Homapage and Detecting software from " + response.url);
$.ajax({
type: "POST",
url: my_url,
dataType: "json",
data: myData,
success: parse_jdata,
error: end_error
})
} else {
$("#responds").append("stop");
end_ajax();
}
}

You should start the next test after you finish processing the previous one.
var new_links_arr = ['site1', 'site2'];
var new_links_index = 0;
function check_server() {
if (new_links_index >= new_links_arr.length) {
return;
}
var this_link = new_links_arr[new_links_index];
if (this_link.length > 5) {
$("#responds").append("<hr/> start analyzing site: " + this_link + "");
var myData = {
mod: 'chk_srv',
url: this_link,
mk_rds_dir: 1
};
$.ajax({
type: "GET",
url: my_url,
dataType: "json",
data: myData,
cache: false,
success: grab_site,
error: end_error
});
}
}
function grab_site(response) {
$("#responds").append(" " + response.the_msg + " ");
var status = response.status;
if (status == 1) {
$("#responds").append(" start grabbing site ");
var myData = {
mod: 'chk_home',
url: response.url
};
$("#Loding_info").html("Get Homepage and Detecting software from " + response.url);
$.ajax({
type: "POST",
url: my_url,
dataType: "json",
data: myData,
success: parse_jdata,
error: end_error
})
} else {
$("#responds").append("stop");
end_ajax();
}
}
function parse_jdata(response) {
// do your processing
// ...
new_links_index++;
check_server();
}

My code was long (more than 10 functions). So I cut some piece of it and made a new array (The real array is made by php from previous response and post by json). This is the reason of mistakes in the code.
The idea by Barmar (incrementing the array index in the final function) was helpful. I changed my code and it is working nice now. Thank you for your help.
I added the new function for sending sites one by one to the next functions:
function walk_in_links_arr(new_links_arr2)
{
if (new_links_index >= new_links_arr2.length)
{
//alert(' new_links_index11 = ' + new_links_index);
$("#responds").append("all sites checking done. ");
pass_response_final();
}
var this_link = new_links_arr2[new_links_index];
//alert(' new_links_index22 = ' + new_links_index);
//alert (this_link);
if(this_link.length>5)
{
$("#responds").append(" start checking " + this_link + " ");
var myData = 'mod=chk_srv&url='+ encodeURIComponent(this_link)+'&mk_rds_dir=1';
$.ajax({
type: "GET",
url: my_url,
dataType:"json",
data:myData,
cache: false,
success:grab_site,
error:end_error
});
}
else
{
new_links_index++;
walk_in_links_arr(new_links_arr);
}
}

Related

JQuery click 1 does nothing

I have a feeling there is something wrong with my for loop. When my websites event is activated the first time, I get no response. It works as intended every time after that. I have tried tuning the numbers in the for loop looking for mistakes but as far as what I've tried. It works best as is.
For the full app: https://codepen.io/xcidis/full/KvKVZb/
var reference = [];
function random() {
$.ajax({
url: "https://api.forismatic.com/api/1.0/?",
dataType: "jsonp",
data: "method=getQuote&format=jsonp&lang=en&jsonp=?",
success: function(quote) {
reference.push([quote.quoteText + "<br/><br/><br/><div align='right'>~" + quote.quoteAuthor + "</div>"]);
}
});
}
$("button").click(function(){
random();
for(i=0;i<4; i++){
if(reference[reference.length-1] == undefined){continue}else{
var boxes = $("<div id='boxes'></div>").html("<p>" + reference[reference.length-1] + "</p>");
$('body').append(boxes);
break;
};
};
});
Your rest of the code ran before your ajax push the value to reference variable.
https://www.w3schools.com/xml/ajax_intro.asp
You can either put your page rendering code within the ajax or use some tips to run the rederer synchronously
$("button").click(function(){
$.when( $.ajax({
url: "https://api.forismatic.com/api/1.0/?",
dataType: "jsonp",
data: "method=getQuote&format=jsonp&lang=en&jsonp=?",
success: function(quote) {
reference.push([quote.quoteText + "<br/><br/><br/><div class='tweet' align='left'></div><div align='right'>~" + quote.quoteAuthor + "</div>"]);
}
})).then(function() {
console.log(reference)
for(i=0;i<4; i++){
if(reference[reference.length-1] == undefined){continue}else{
var boxes = $("<div id='boxes'></div>").html("<p>" + reference[reference.length-1] + "</p>");
$('body').append(boxes);
break;
};
};
});
});

JavaScript/jQuery callback using Ajax

I'm having trouble with my functions running before Ajax requests (the first to a local JSON, the second to an online resource) have finished.
In this example I want countTheMovies to run at the end after my application has got all the information it needs and populated the divs. Instead it's running straight away.
I tried to delay it using an if condition, but with no joy. I've also tried with callbacks, but think I must be getting those wrong (I'm assuming callbacks are the answer). I'm aware of timed delays, but because in the actual project I'm sourcing 250+ movies (and because a timed delay seems like cheating) I thought I'd ask here instead.
Can anyone recommend JavaScript or jQuery code to fix this problem?
$(function(){
getMovieList();
});
function getMovieList() {
$.ajax({
url: "movielist.json",
type: "GET",
dataType: "JSON",
success: function(data) {
for (var i = 0; i < data.length; i++) {
var title = data[i].title.toLowerCase().split(" ").join("+");
var year = data[i].year;
i === data.length - 1
? getMovieInfo(title, year, true)
: getMovieInfo(title, year, false);
}
}
});
}
function getMovieInfo(title, year, isLast) {
$.ajax({
url: "https://www.omdbapi.com/?t=" + title + "&y=" + year + "&plot=short&r=json",
type: "GET",
crossDomain: true,
dataType: "JSON",
success: function(val) {
if (!val.Error) {
movie = title.replace(/[^a-z0-9\s]/gi, '');
$("#app").append(
// appending info to divs
);
}
}
});
if (isLast) countTheMovies();
};
function countTheMovies() {
$("#app").append("There are " + $(".movie").length + " movies.");
}
A plunker of my failings: https://plnkr.co/edit/0mhAUtEsaOUWhkZMJqma?p=preview
You've almost got it!
The same way that you call getMovieInfo in the success callback of getMovieList, you should be calling countTheMovies in the success callback of getMovieInfo.
As Jacob said above, move the countTheMovies call inside the AJAX request.
$(function(){
getMovieList();
});
function getMovieList() {
$.ajax({
url: "movielist.json",
type: "GET",
dataType: "JSON",
success: function(data) {
for (var i = 0; i < data.length; i++) {
var title = data[i].title.toLowerCase().split(" ").join("+");
var year = data[i].year;
i === data.length - 1
? getMovieInfo(title, year, true)
: getMovieInfo(title, year, false);
}
}
});
}
function getMovieInfo(title, year, isLast) {
$.ajax({
url: "https://www.omdbapi.com/?t=" + title + "&y=" + year + "&plot=short&r=json",
type: "GET",
crossDomain: true,
dataType: "JSON",
success: function(val) {
if (!val.Error) {
movie = title.replace(/[^a-z0-9\s]/gi, '');
$("#app").append(
// appending info to divs
);
if (isLast) countTheMovies();
}
}
});
};
function countTheMovies() {
$("#app").append("There are " + $(".movie").length + " movies.");
}
Just put your countTheMovies() logic inside of the success callback of the AJAX request in getMovieInfo if you want it to run on success.
You can call your countTheMovies() function from inside the success field of your Ajax call. This way it will make the function call when you intend it to.
Try out this
$(function(){
getMovieList();
});
function getMovieList() {
$.when( $.ajax({
url: "movielist.json",
type: "GET",
dataType: "JSON",
success: function(data) {
for (var i = 0; i < data.length; i++) {
var title = data[i].title.toLowerCase().split(" ").join("+");
var year = data[i].year;
i === data.length - 1
? getMovieInfo(title, year, true)
: getMovieInfo(title, year, false);
}
}
}) ).then(function( data, textStatus, jqXHR ) {
countTheMovies();
});
}
function getMovieInfo(title, year, isLast) {
$.ajax({
url: "https://www.omdbapi.com/?t=" + title + "&y=" + year + "&plot=short&r=json",
type: "GET",
crossDomain: true,
dataType: "JSON",
success: function(val) {
if (!val.Error) {
movie = title.replace(/[^a-z0-9\s]/gi, '');
$("#app").append(
// appending info to divs
);
}
}
});
};
function countTheMovies() {
$("#app").append("There are " + $(".movie").length + " movies.");
}

ajax success event doesn't work after being called

After searching here on SO and google, didn't find an answer to my problem.
The animation doesn't seem to trigger, tried a simple alert, didn't work either.
The function works as it is supposed (almost) as it does what i need to, excluding the success part.
Why isn't the success event being called?
$(function() {
$(".seguinte").click(function() {
var fnome = $('.fnome').val();
var fmorada = $('.fmorada').val();
var flocalidade = $('.flocalidade').val();
var fcodigopostal = $('.fcodigopostal').val();
var ftelemovel = $('.ftelemovel').val();
var femail = $('.femail').val();
var fnif = $('.fnif').val();
var fempresa = $('.fempresa').val();
var dataString = 'fnome='+ fnome + '&fmorada=' + fmorada + '&flocalidade=' + flocalidade + '&fcodigopostal=' + fcodigopostal + '&ftelemovel=' + ftelemovel + '&femail=' + femail + '&fnif=' + fnif + '&fempresa=' + fempresa;
$.ajax({
type: "GET",
url: "/ajaxload/editclient.php",
data: dataString,
success: function() {
$('.primeirosector').animate({ "left": "+=768px" }, "fast" );
}
});
return false;
});
});
you are trying to pass query string in data it should be json data.
Does your method edit client has all the parameters you are passing?
A simple way to test this is doing the following:
change this line to be like this
url: "/ajaxload/editclient.php" + "?" + dataString;
and remove this line
data: dataString
The correct way of doing it should be, create a javascript object and send it in the data like so:
var sendData ={
fnome: $('.fnome').val(),
fmorada: $('.fmorada').val(),
flocalidade: $('.flocalidade').val(),
fcodigopostal: $('.fcodigopostal').val(),
ftelemovel: $('.ftelemovel').val(),
femail: $('.femail').val(),
fnif: $('.fnif').val(),
fempresa: $('.fempresa').val()
}
$.ajax({
url: "/ajaxload/editclient.php",
dataType: 'json',
data: sendData,
success: function() {
$('.primeirosector').animate({ "left": "+=768px" }, "fast" );
}
});
Another thing shouldn't this be a post request?
Hope it helps

Why the text before Ajax call is not display?

function pdfToImgExec(file, IsfirstLogging, folder, round) {
alert(file);
var postString = file + '&' + IsfirstLogging + '&' + folder + '&' + round;
var errorMsg = (folder == 'Incoming' ? '<p>error in incoming folder</p>' : '<p>error in other folder</p>');
$.ajax({
type: "POST",
cache: false,
async: false,
url: "pdfToImgExec.php",
data: {
"data": postString
},
dataType: "html",
beforeSend: function () {
alert(file + 'a');
$('#pdfToImgResult').html('<p>Converting' + file + ', Please wait......</p>');
},
success: function (data) {
if(data == '1') {
$('#pdfToImgResult').html('<p>Complete convert ' + file + '</p>');
} else if(round < 4) {
$('#pdfToImgResult').html('<p>Fail to convert , retry ' + round + ' round <img src="loading.gif" height="20" width="20"/></p>');
round++;
pdfToImgExec(file, 'false', folder, round);
} else {
folder == 'Incoming' ? tempFailIncomingFiles.push(file) : tempFailResultFiles.push(file);
}
},
error: function (x, t, m) {
$('#pdfToImgResult').html(errorMsg);
alert(t);
releaseBtn();
}
});
}
The problem of this ajax call is I can alert the (file + 'a') in the beforeSend function , but the
$('#pdfToImgResult').html('<p>Converting' + file + ', Please wait......</p>');
is not working, it will not display anything but only jumped to the
$('#pdfToImgResult').html('<p>Complete convert ' + file + '</p>');
after the ajax call is finished.
Is it due to async:false? How to fix the problem ? thanks.
It's because you're using async: false,, so the function blocks until the request is complete, preventing a redraw until everything is done.
You seem to be all set up with callbacks, so there doesn't seem to be any reason to make a blocking xhr request. Just remove the async: false,, and you should be all set.
Here's a quick example of how to deal with asynchronous code. I've removed most of your code to keep it brief.
// --------------------------------new parameter-------------v
function pdfToImgExec(file, IsfirstLogging, folder, round, callback) {
// your code...
$.ajax({
type: "POST",
cache: false,
// async: false, // Remove this line!
url: "pdfToImgExec.php",
data: {
"data": postString
},
dataType: "html",
beforeSend: function () {
$('#pdfToImgResult').html('<p>Converting' + file + ', Please wait......</p>');
},
success: function (data) {
// your code...
// Invoke the callback, passing it the data if needed
callback(data)
},
error: function (x, t, m) {
// your code;
}
});
}
When you call pdftoImgExec, pass a function as the last parameter that will be invoked when the response is complete. That function is where your code resumes.
pdfToImgExec(..., ..., ..., ..., function(data) {
// resume your code here.
alert(data);
})

Pausing for loop after every execution

i have a page, wherein i am using a ajax for inserting records... now in javascript i am using a for each loop to loop the html table and insert the rows in database. but happens is as foreach loop executes fast, it sometime, does not insert some records.. so i want to make the loop sleep for sometime once it has executed first and thereafter...
is there any way to pause the for loop.. i used setTImeout.. but it just delay it first time and not consecutive times...
here's my code.
function AddTopStories() {
$("#tBodySecond tr").each(function (index) {
$.ajax({
type: "POST",
url: "AjaxMethods.aspx/AddTopStoriesPosition",
data: "{'articleID':'" + $("td:nth-child(1)", this).text() + "','siteID':1}",
dataType: "json",
contentType: "application/json",
success: function (data) {
window.setTimeout(showSuccessToast(data.d), 3000);
},
error: function (data) {
window.setTimeout(showSuccessToast("Error:" + data.reponseText), 3000);
}
});
});
}
Please help me to resolve this issue... its utmost important.
*************************************UPDATED CODE AS PER THE CHANGES BY jfriend00*********
function AddTopStories() {
var stories = $("#tBodySecond tr");
var storyIndex = 0;
function addNext() {
if (storyIndex > stories.length) return; // done, no more to get
var item = stories.get(storyIndex++);
alert($("td:nth-child(1)", item).text());
addNext();
}
}
This just does not do anything... does not alert...
I'd recommend you break it into a function that does one story and then you initiate the next story from the success handler of the first like this:
function AddTopStories() {
var stories = $("#tBodySecond tr");
var storyIndex = 0;
function addNext() {
if (storyIndex >= stories.length) return; // done, no more to get
var item = stories.get(storyIndex++);
$.ajax({
type: "POST",
url: "AjaxMethods.aspx/AddTopStoriesPosition",
data: "{'articleID':'" + $("td:nth-child(1)", item).text() + "','siteID':1}",
dataType: "json",
contentType: "application/json",
success: function (data) {
addNext(); // upon success, do the next story
showSuccessToast(data.d);
},
error: function (data) {
showSuccessToast("Error:" + data.reponseText);
}
});
}
addNext();
}
Ugly, but you can fake a javascript 'sleep' using one of the methods on this website:
http://www.devcheater.com/

Categories

Resources