Stopping an $.ajax call on page unload - javascript

I have a procedure running on a timeout to load data in the background:
(function getSubPage() {
setTimeout(function() {
if (cnt++ < pagelist.length) {
loadSubPage(pagelist[cnt]);
getSubPage();
}
}, 500);
})();
In loadSubPage() I'm making $.ajax() calls:
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
$.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
}
});
initSubPages[page] = true;
}
}
The problem I'm having is that the error handler is being hit when the user navigates away if any ajax requests are open. I'm trying to get around this by .stop()ing the requests on window.onbeforeunload, but I'm not sure what object to call .stop() on?

jQuery exposes the XMLHttpRequest object's abort method so you can call it and cancel the request. You would need to store the open request into a variable and call abort().
activeRequest = $.ajax({...
and to stop it
activeRequest.abort()

Abort Ajax requests using jQuery
This should come in handy.. You have a jQuery method for doing just that.

The $.ajax returns XMLHTTPRequestObject which has .abort function. This function will halt the request before it completes.
var xhr = $.ajax({ /*...*/
..
..
/* Later somewhere you want to stop*/
xhr.abort();
Read more: How to cancel/abort jQuery AJAX request?

Here is the solution I used based on the feedback:
window.onbeforeunload = function() {
for (page in ajaxing) {
if (ajaxing[page] != null)
ajaxing[page].abort();
}
};
var ajaxing = {};
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
var ajaxRequest = $.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
},
complete: function() {
ajaxing[lot] = null;
}
});
ajaxing[page] = ajaxRequest;
initSubPages[page] = true;
}
}

Related

How to abort ajax request on page refresh

I have a form, on submit of that I am making an ajax request which is sometimes taking time to get the request, so what I am trying to do is whenever user refresh or clicks back button of the browser after form submitting i want to abort that ajax call
What I am doing is
$("#formId").submit(function(event) {
event.preventDefault();
var xhr = $.ajax({
url : "Drilldown",
method : "GET",
success : function(data) {
// here doing ,my stuff
},
complete : function() {
$('.loader').hide();
$('.overlay').hide();
}
});
window.onbeforeunload = function() {
return "some message"; // here when user clicks on leave then want to abort like `xhr.abort`
};
});
whenever the user clicks on leave I want to abort my ajax request
How can I do that?
**I specifically want to do that when ever form submit and once form is submitted,i want to abort that function also onbeforeunload **
You can directly xhr.abort() in "onbeforeunload" event handler method:
// Define xhr variable outside so all functions can have access to it
var xhr = null;
$("#formId").submit(function(event) {
event.preventDefault();
xhr = $.ajax({
url: "Drilldown",
method: "GET",
success: function(data) {
// here doing ,my stuff
},
complete: function() {
$('.loader').hide();
$('.overlay').hide();
}
});
});
window.onbeforeunload = onUnload;
function onUnload() {
if(xhr) xhr.abort();
return "some message";
};
call below method to abort ajax call
xhr.abort()

How to restrict multiple user logins at same time using JavaScript / jQuery

I have developed an ASP.NET MVC Application using JavaScript, jQuery.
I have implemented to be restrict multiple user logins at same time using onbeforeunload/beforeunloadevent.
It works fine, but sometimes not working in onbeforeunload/beforeunloadevent.
var myEvent = window.attachEvent || window.addEventListener;
var chkevent = window.attachEvent ? 'onbeforeunload' : 'beforeunload'; /// make IE7, IE8 compitable
myEvent(chkevent, function (e) { // For >=IE7, Chrome, Firefox
if (!validNavigation)
{
$.ajax({
url: '#Url.Action("ClearSession", "Account")',
type: 'Post',
data: "",
dataType: "json",
success: function (data)
{
console.log("onbeforeunload Success")
},
error: function (data) {
console.log("onbeforeunload Error")
}
});
}
return null;
});
There is one also function in AJAX - jQuery is called complete: function(){};
This function checks weather request is running for same user id and password on browser or not, Like this here
complete: function() {
$(this).data('requestRunning', false);
}
Whole AJAX-jQuery implementation here see and implement accordingly, I hope it will work fine for you
Code Here
$('#do-login').click(function(e) {
var me = $(this);
e.preventDefault();
if ( me.data('requestRunning') ) {
return;
}
me.data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
me.data('requestRunning', false);
}
});
});
See this me.data('requestRunning', false); if it will get any request running for same user id and password it returns false and cancel login.
For more help see here link Duplicate, Ajax prevent multiple request on click
This is not perfect solution but you can implement like this

How to press a button after successful Ajax?

When Ajax call is successful, user gets redirected to main page:
$('#button_1').on('click', function () {
//code
$.ajax({
method: "POST",
url: "/somewhere",
data: {
//code
}
}).done(function () {
location.href = "/";
});
});
After getting redirected, I want to automatically click another button, which opens a modal. I tried inside done function different methods:
.done(function () {
location.href = "/";
$('#button_2').click(); // doesn't work
});
.done(function () {
location.href = "/";
setTimeout(function ()
$('#button_2').click(); // doesn't execute
}, 2000);
});
.done(function () {
location.href = "/";
$(document).ready( function () {
// executes but user is immediately redirected to main page
$('#button_2').click();
});
});
I also tried outside Ajax, in the function that Ajax call is in, but had the same results.
How can I click the button programmatically after the Ajax call?
You need to add that logic in the target (main) page.
Once you redirect, the current page is not longer the active one and all logic is removed.
You could add some parameter to the URL in order to know when you are there due to redirection, something like:
location.href="/?redirect=1"
and then check that parameter
The lines of code next to
location.href = "/";
will not be executed because the browser is navigating to another page.
So you should put your logic in the / page (#button_2 should be in that page).
You're currently trying to execute code after a redirect which isn't possible directly because the code after location.href = "/" will never be reached. Once you redirect you've have a fresh page with a clear state.
Your current function can still look like this:
$('#button_1').on('click', function () {
$.ajax({
method: "POST",
url: "/somewhere",
data: {
//code
}
}).done(function () {
location.href = "/?modal-open=1";
});
});
As you can see I've added a query parameter to the redirect so we know we were redirected with the intention to open the modal.
For your Root Page (/) you will need a script like this:
$(document).ready( function () {
// check the URL for the modal-open parameter we've just added.
if(location.search.indexOf('modal-open=1')>=0) {
$('#button_2').click();
}
});
This will check if the parameter is in the URL and trigger the click.
First of all when you redirect a new page you can not access DOM because the page is reloaded. You can send a parameter for do that.
$(document).ready( function () {
//after page load
var isButtonActive = findGetParameter("isButtonActive");
if(isButtonActive){
alert("button_2 activated");
$('#button_2').click();
}
$('#button_1').on('click', function () {
//code
$.ajax({
method: "POST",
url: "/somewhere",
data: {
//code
}
}).done(function () {
alert("page will be reload. button_2 wil be activated");
location.href = "/?isButtonActive=true";
});
});
$('#button_2').on('click', function () {
alert("button_2 clicked");
});
});
function findGetParameter(parameterName) {
var result = null,
tmp = [];
location.search
.substr(1)
.split("&")
.forEach(function (item) {
tmp = item.split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
});
return result;
}
Thank you for your answers. I researched a bit more and found another way to do it:
$('#button_1').on('click', function () {
sessionStorage.setItem("reload", "true");
//code
$.ajax({
method: "POST",
url: "/somewhere",
data: {
//code
}
}).done(function () {
location.reload();
});
});
And in main page:
$(document).ready(function () {
var reload = sessionStorage.getItem("reload");
if (reload == "true") {
$("#button_2").click();
sessionStorage.setItem("reload", false);
}
});

Calling a function until jQuery .post finishes loading

I'm a little new to jQuery framework and while using AJAX with normal javascript I used readyState() function to display a loading gif image. But, I don't know how to use that in jQuery .post() method. Was it possible to add a class until it finishes loading? If so, please give a code sample. My function is similar to this:
$.post("verify.php",{
username: u,
password: p
},function(r) {
if(r == 1) {
$(".elmt").addClass("loading");
} else if (r == 0) {
location.href = 'http://localhost';
}
});
I always prefer using $.ajax for things like this as it has more options than the shortcuts :
$.ajax({
type: 'POST',
url : 'verify.php',
data: {
username: u,
password: p
},
beforeSend: function () {
$(".elmt").addClass("loading"); // add loader
}
}).always(function() { // always executed
$(".elmt").removeClass("loading"); // remove loader
}).done(function(r) { // executed only if successful
if (r == 0) {
location.href = '/';
}
});
Just call the addClass before the $.post() and be done with it
$(".elmt").addClass("loading");
$.post("verify.php", {
username: u,
password: p
}, function (r) {
location.href = 'http://localhost';
});
You could fire a custom event before starting your AJAX request.
Then in your success function, fire another to stop.
Or if you just want the loading animation:
$(".elmt").addClass("loading");
$.post("verify.php",{
username: u,
password: p
},function(r) {
$(".elmt").removeClass("loading");
// etc...
});
There is a global way to do this using ajaxStart() and ajaxStop(). See How to show loading spinner in jQuery?
If you need to do for all your requests. You could try:
$(document).ajaxStart(function(){
$(".elmt").addClass("loading");
});
$(document).ajaxStop(function(){
$(".elmt").removeClass("loading");
});
But it's not so cool to always display the loading when the request takes little time as it will cause the screen flicking. Try:
var timer;
$(document).ajaxStart(function(){
timer = setTimeout(function(){
$(".elmt").addClass("loading");
},1500);
});
$(document).ajaxStop(function(){
clearTimeout(timer);
$(".elmt").removeClass("loading");
});
By adding a timer, only requests that take longer than 1.5 seconds should be considered long and display a loading icon.
As you see on code below you can do your work on different results of post method
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.post("example.php", function() {
alert("success");
})
.done(function() { alert("second success"); })
.fail(function() { alert("error"); })
.always(function() { alert("finished"); });
// perform other work here ...
// Set another completion function for the request above
jqxhr.always(function(){ alert("second finished"); });

Ajax request in progress jQuery

Is there a way to check if there's ajax request in progress?
Something like:
if ( $.ajax.inProgress ){ do this; } else { do that; }
yes there is
$.ajax({
type: 'get',
url: 'url',
data: {
email: $email.val()
},
dataType: 'text',
success: function(data)
{
if(data == '1')
{
$response.attr('style', '')
.attr('style', "color:red;")
.html('Email already registered please enter a different email.');
}
else
{
$response.attr('style', '')
.attr('style', "color:green;")
.html('Available');
}
},
beforeSend: function(){
$email.addClass('show_loading_in_right')
},
complete: function(){
$email.removeClass('show_loading_in_right')
}
});
the beforeSend will do the process you need to do when the ajax request has just started and complete will be called when the ajax request is complete.
documentation
To abort ajax request,
Use
if($.active > 0){
ajx.abort();//where ajx is ajax variable
}
To continue running ajax request,
Use
if($.active > 0){
return;
}
You should basically set a variable on top of script set to false and on ajax initiate set it to true and in the success handler set it to false again as described here.
You might like this:
$(document).ready(function() {
var working = false;
$("#contentLoading").ajaxSend(function(r, s) {
$(this).show();
$("#ready").hide();
working = true;
});
$("#contentLoading").ajaxStop(function(r, s) {
$(this).hide();
$("#ready").show();
working = false;
});
$('#form').submit(function() {
if (working) return;
$.post('/some/url', $(this).serialize(), function(data){
alert(data);
});
});
});
If you are in full control of the javascript code you could increment a variable whenever you start an ajax request and decrement it when the request completes (with success, failure or timeout). This way you always know if there is a request in progress.

Categories

Resources