Ajax is not aborting when stop button is clicked - javascript

I have this code, and when the stop button is clicked, I need to stop the ajax, but for some reason ajax is not aborting.
var started = false;
$(document).ready(function () {
$('#start').click(function () {
var count = $("#names").val();
var line = count.split("\n");
started = true;
line.forEach(function(value, index) {
setTimeout(
var ajaxCall = $.ajax({
url: url,
type: 'GET',
data: someData,
success: function(result) {
//some works here
}
});
$('#stop').click(function () {
ajaxCall.abort(); //abort Ajax
$('#check').attr('disabled', false);
$('#stop').attr('disabled', 'disabled');
})
}, 2000 * index);
});
});
});

Related

Why do the ajax requests fire multiple times

I have a form inside a modal that either saves a memo when one button is clicked or deletes it when another is clicked. The items get saved/deleted but the request count multiplies with each click. I'm getting 4 of the same request etc. How do i stop this. do i have to unbind something?
$('#modal').on('show.bs.modal', function (e) {
var origin = $(e.relatedTarget);
var memoId = origin.attr('data-id');
$('#modal').click(function(event){
if($(event.target).hasClass('memo-save')) {
event.preventDefault();
var memoText = $(event.target).parent().parent().find('textarea').val();
var memo = {
memo: memoText,
id: memoId
}
$.ajax({
type: "POST",
url: '/memos/add-memo?memo=' +memo+'&id=' + memoId,
data: memo,
success: function (result) {
$(event.target).toggleClass('active').html('Memo Saved');
}
});
} else if($(event.target).hasClass('memo-delete')) {
event.preventDefault();
var memoText = "";
var memo = {
id: memoId
}
$.ajax({
type: "POST",
url: '/memos/remove-memo?id=' + itemId,
data: memo,
success: function (result) {
$(event.target).toggleClass('active').html('Memo Deleted');
}
});
}
});
});
you can move the $('#modal').click outside the $('#modal').on('show.bs.modal' that way it will not re-add the listener each time the modal is shown

How to wait untill for (append) finished and then show result javascirpt / jquery

I have a function that renders 5 images, and pagination. This function used ajax for getting data.
It works well, but when I using the pagination, I can see the process of 'creating' HTML.
I want to add a loading.gif, until all the HTML finished loading, and show all the results
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) {
isCurrentPage = true;
}
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
} else {
errors += data.error;
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
}
});
}
I saw tutorials about promises and callbacks, but I'm not good at it and I don't know how to rewrite my code for those. Is there another way to solve the issue ?
solution: It may come in handy for other:
function hideLoader() { setTimeout(function () { $('.loader-sm').hide(); }, 750); }
function showLoader() { $('.loader-sm').show(); }
function hideList() { $('#imgList').hide(); }
function showList() { setTimeout(function () { $('#imgList').show(200); }, 750); }
success: function () {
if (data.success) {
//do something
} else {
showList();
hideLoader();
}
},
error: function () {
showList();
hideLoader();
},
complete: function () {
showList();
hideLoader();
}
have a class for show loading image icon and place it in the block itself and hide it once completed. have a look at the below sample. it may helpful to you.
beforeSend: function() {
$('#imgList').addClass('loading');
},
success: function(data) {
$("#imgList").removeClass('loading');
},
error: function(xhr) { // if error occured
$("#imgList").removeClass('loading');
},
complete: function() {
$("#imgList").removeClass('loading');
}
otherwise you can have a loader div block show the block on beforesend() and hide it in success / complete.
You can do like this i am not sure about but it will help you
function getImages(init, buttonPaging) {
var data = {};
if (init) {
data["int"] = "1";
} else {
data["int"] = $(buttonPaging).text();
}
let promise = new Promise(function(resolve, reject) {
//add your code for add loading.gif
$.ajax({
type: "POST",
url: '#Url.Action("GetImages", "Image")',
data: JSON.stringify(data),
beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val()); },
contentType: "application/json",
dataType: "json",
success: function (data) {
if (data.success) {
$('#imgList').children().remove();
for (var i = 0; i < data.imageList.length; i++) {
(function (img) {
$('#imgList').append(drawList(img, data.baseUrl));
})(data.imageList[i]);
}
$('#pagingList').children().remove();
for (var i = 0; i < data.pagingInfo.totalPages; i++) {
(function (paging) {
var isCurrentPage = false,
index = i;
index++;
if (paging.currentPage == index) { isCurrentPage = true; }
$('#pagingList').append(drawPaging(index, isCurrentPage));
})(data.pagingInfo);
}
resolve();
} else {
errors += data.error;
resolve();
}
},
error: function () {
errors += 'Please contact with administrator - img list at edit product';
alert(errors);
resolve();
}
});
}
promise.then(
result => alert("done"), // remove loading.gif
);
}

How to set delay for multiple ajax calls and bind a stop button to them?

I'm building a small app to make multiple ajax calls to the server. Each call should be made in sequence and the interval is 1 sec. And if the stop button is clicked, all remaining calls should be aborted. I've tried code like below but couldn't make it to work. The time interval doesn't work, and I've no idea where I should bind the stop button.
<button id="startbtn">Start!</button>
<button id="stoptbn">Stop!</button>
<script>
function makeajax(num) {
$.ajax({
type: "POST",
url: "/testurl",
data: {
num: num
},
complete: function (result) {
console.log(num);
setTimeout(makeajax, 1000);
} } )
};
$(document).ready(function () {
$("#startbtn").click(function () {
var data_array = [1, 2, 3];
for (var i=0; i < data_array.length; i++) {
makeajax(data_array[i]);
};
</script>
don't use a for loop statement:
<button id="startbtn">Start!</button>
<button id="stoptbn">Stop!</button>
<script>
var xhrs = [];
function makeajax(arr) {
if (arr !== null && arr.length > 0){
var num = arr.shift();
var xhr = new XMLHttpRequest();
xhrs.push(xhr);
$.ajax({
type: "POST",
url: "/testurl",
xhr : function(){
return xhr;
},
data: {
num: num
},
complete: function (result) {
if (!(xhr.readyState === 4 && xhr.status === 0)) {
console.log(num);
setTimeout(() => makeajax(arr), 1000);
}
}
});
}
}
$(document).ready(function () {
$("#startbtn").click(function () {
var data_array = [1, 2, 3];
makeajax(data_array);
});
$("#stopbtn").click(function () {
xhrs.forEach(xhr => xhr.abort());
});
});
</script>
One way is this. If you want to stop calling the next ajax query, but still handle the one that was in progress.
var callNr = 0;
var stopId;
var data_array = [1, 2, 3];
var isStopped;
function makeajax() {
if (!data_array.length || isStopped) { alert('no more queries'); return;}
num = data_array.shift();
callNr++;
$.ajax({
type: "POST",
url: "/testurl",
data: {
num: num
},
complete: function (result) {
console.log(num);
if (!isStopped) {
stopId = setTimeout(makeajax, 1000);
}
$("#response").text('Response nr:' + callNr);
} } );
};
$(document).ready(function () {
$("#startbtn").click(function () {
isStopped = false;
makeajax();
});
$("#stoptbn").click(function() {
clearTimeout(stopId);
isStopped = true;
console.log('stopped');
});
});
<button id="startbtn">Start!</button>
<button id="stoptbn">Stop!</button>
<button id="response">No response yet</button>
JsFiddle
chcek this,
function makeajax(num) {
jqXHR = $.ajax({
type: "POST",
url: "/testurl",
async : false,
data: {
num: num
},
success: function (result) {
//Do anything you want
},
timeout: 3000
};
$("#abortAjax").click(function() { // Id of the button you want to bind
$(jqXHR).abort();
});
}

jQuery wait for .each to finish and run ajax call

I have the following code:
var allChecks = [];
$('input[type=text]').each(function () {
var key = $(this).attr("id");
allChecks[key] = [];
}).promise()
.done(function () {
$('input[type=checkbox]').each(function () {
if (this.checked) {
var ref = $(this).attr('id');
$('.' + ref).each(function () {
allChecks[ref].push({
amount: $("#" + ref).text()
});
});
} else {
allChecks[ref].push({
amount: 0.00
});
}
}).promise()
.done(function () {
$.ajax({
cache: false,
type: 'POST',
data: {
allChecks: allChecks
},
url: '/process',
beforeSend: function () {
console.log("Processing your checks please wait...");
},
success: function (response) {
console.log(response);
},
error: function () {
console.log("Error");
}
});
});
});
My Ajax call runs but I see no data passed as parameters, like if the array allChecks is empty. As JavaScript runs synchronously, I'm expecting that whatever I place after each() will not run until each() is complete, so the Ajax call should run fine and nor give me no data passed as if the array allChecks is empty. Any help or solution on this would be appreciated. Thanks.

Kill Ajax Session Outside of Originating Function

I have an AJAX function I'd like to kill, but it is outside of the function. Take a look:
function waitForMsg(){
var heartbeat = $.ajax({
type: "GET",
url: "includes/push_events.php",
tryCount : 0,
retryLimit : 3,
async: true,
cache: false,
// timeout: 500,
success: function(data){
console.log(data);
if(data){
if(data.current_date_time){
updateTime(data.current_date_time);
}
if(data.color){
console.log("Receiving data");
displayAlert(data.color, data.notification_message, data.sound, data.title);
}
if(data.user_disabled){
console.log("Receiving data");
fastLogoff();
checkDisabled();
}
}
setTimeout(
waitForMsg,
5000
);
},
error: function(data){
if (data.status == 500) {
console.log("Connection Lost to Server (500)");
$.ajax(this);
} else {
console.log("Unknown Error. (Reload)");
$.ajax(this);
}
},
dataType: "json"
});
};
// Detect browser open.
$(document).ready(function(){
// window.onunload = function(){alert('closing')};
// mainmode();
$('#alertbox').click(function(){
$('#alertbox').slideUp("slow");
});
$(document).ready(function(){
$('#alertbox').click(function(){
$('#alertbox').slideUp("slow");
});
// Check focal point
var window_focus = true;
$(window).focus(function() {
window_focus = true;
console.log('Focus');
});
$(window).blur(function() {
window_focus = false;
console.log('Blur');
});
setInterval(function(){
if(window_focus == true){
console.log('in focus');
waitForMsg();
}else{
console.log('out of focus');
heartbeat.abort();
}
}, 5000);
});
});
If you notice, the ajax is outside of the document.ready. I am trying to kill the ajax calls if the user goes to a different window, then restart the calls once the return to the window. The start works, but if the user goes away from the window, it gives me the "heartbeat is not defined". Obviously this is because its outside of that function. Any work arounds?
I'd refactor a bit the code to avoid the usage of setInterval and clean up a bit the code.
You can abstract the logic in an object, let's say Request. You can add two methods to resume and stop which will handle the status of the underlying AJAX request.
var Request = function(options){
var request = this, xhr = null, aborted = false;
/* Resumes the operation.
* Starts a new request if there's none running.
*/
request.resume = function() {
aborted = false;
request.retry();
};
/* Retry loop.
*/
request.retry = function(){
if(!xhr) {
xhr = $.ajax(options).done(function(){
request.destroy();
!aborted && setTimeout(function(){
request.retry();
}, options.timeout);
});
}
};
/* Aborts the current operation.
*/
request.abort = function(){
aborted = true;
if(xhr) xhr.abort();
request.destroy();
};
/* Destroy.
*/
request.destroy = function(){
xhr = null;
};
return request;
};
Now, you can drop the setInterval.
$(function () {
var request = new Request({
type: "GET",
url: "includes/push_events.php",
timeout: 5000,
success: function(data){
/* Success handler */
},
error: function(data){
/* Error handler */
},
dataType: "json"
});
$(window).focus(function () {
request.resume();
}).blur(function () {
request.abort();
});
request.resume();
});
The Request constructor receives the $.ajax options which should contain an additional timeout parameter that specifies the delay between requests.
You need to stop further request after window.blur. restart request after window.focus.
Modified code
var setTimeoutConst;
function waitForMsg(){
if(!window_focus){
return; //this will stop further ajax request
}
var heartbeat = $.ajax({
type: "GET",
url: "includes/push_events.php",
tryCount : 0,
retryLimit : 3,
async: true,
cache: false,
// timeout: 500,
success: function(data){
console.log(data);
if(data){
if(data.current_date_time){
updateTime(data.current_date_time);
}
if(data.color){
console.log("Receiving data");
displayAlert(data.color, data.notification_message, data.sound, data.title);
}
if(data.user_disabled){
console.log("Receiving data");
fastLogoff();
checkDisabled();
}
}
setTimeoutConst= setTimeout(waitForMsg,5000);
},
error: function(data){
if (data.status == 500) {
console.log("Connection Lost to Server (500)");
// $.ajax(this);
} else {
console.log("Unknown Error. (Reload)");
//$.ajax(this);
}
setTimeoutConst= setTimeout(waitForMsg,5000); // continue sending request event if last request fail
},
dataType: "json"
});
};
var window_focus = true;
$(document).ready(function(){
$('#alertbox').click(function(){
$('#alertbox').slideUp("slow");
});
$('#alertbox').click(function(){
$('#alertbox').slideUp("slow");
});
// Check focal point
$(window).focus(function() {
if(window_focus ){return}
window_focus = true;
waitForMsg();
console.log('Focus');
});
$(window).blur(function() {
if(!window_focus ){return}
clearTimeout(setTimeoutConst);
window_focus = false;
console.log('Blur');
});
waitForMsg();
});

Categories

Resources