AJAX stop propagation next calls - javascript

I am making global interceptor of ajax calls, to track some specific responces and prevent next calls.
The local call is:
$.ajax({
contentType: "application/json",
dataType: "json",
method: "PUT",
url: url + '/0'
}).then(function (data) {
console.log('LOCAL: this should not be seen too');
nextUser();
});
The interceptior is
$(document).ajaxStart(function () {
console.log("GLOBAL: start");
}).ajaxSend(function (e, xhr, opts) {
console.log("GLOBAL: send");
}).ajaxError(function (e, xhr, opts) {
console.log("GLOBAL: error");
}).ajaxSuccess(function (e, xhr, opts) {
if (xhr.responseJSON.test) {
$('#upgradeModal').modal('show');
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
// change status code
xhr.abort();
return false;
}
console.log("GLOBAL: this should not be seen");
}).ajaxComplete(function (e, xhr, opts) {
console.log("GLOBAL: complete");
}).ajaxStop(function () {
console.log("GLOBAL: stop");
});
Really I need to thack ajaxSuccess or ajaxComplete but others put here just to test.
The result is
GLOBAL: start
GLOBAL: send
GLOBAL: complete
GLOBAL: stop
LOCAL: this should not be seen too
So this console.log
"GLOBAL: this should not be seen"
is not shown correct, but I need not to see this
"LOCAL: this should not be seen too"
also. As you see I tried everything in code like "stopImmediatePropagation" but still nothing. Is is possible to stop propagation of this ajax call?

Related

Ajax call freeze while process request from callback function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I have created a common ajax call function for my application for optimizing code. the problem is while I call the function its freeze page. Please check below JS:
$(fuction(){
$('.btn').click(function(){
var data = getData('myaction/getinfo', []);
})
});
function getData(url, data) {
var result = "";
$.ajax({
url: url,
type: 'POST',
async: false,
data: data,
error: function () {
console.log('error');
$('.custom-loader').fadeOut("slow");
},
beforeSend: function () {
$('.custom-loader').fadeIn("slow");
},
complete: function () {
$('.custom-loader').fadeOut("slow");
},
success: function (res, status) {
result = res;
$('.custom-loader').fadeOut("slow");
}
});
return result;
}
While I click a button, ajax request working pretty well but loader not showing until ajax return response (unable to click until response return).
If I on async with async: true this will continue execution code which breaks functionality (Next execution depend on ajax response). Can anyone help me with this?
Thanks an advance!
The solution to asynchronous operations is callbacks (unless you use es6 async/await). This means that instead of expecting functions to return values you pass them callbacks, which are functions that take as a parameter the return value.
In your case this would look like,
$(function(){
$('.btn').click(function() {
getData('myaction/getinfo', [], function(res){
console.log(res);
});
})
});
function getData(url, data, callback) {
$.ajax({
url: url,
type: 'POST',
data: data,
error: function () {
console.log('error');
$('.custom-loader').fadeOut("slow");
},
beforeSend: function () {
$('.custom-loader').fadeIn("slow");
},
complete: function () {
$('.custom-loader').fadeOut("slow");
},
success: function (res, status) {
$('.custom-loader').fadeOut("slow");
callback(res);
}
});
}
You should get use to the "callback" mechanisim in Javascripts. Just call your post processing method in the "success" event handler.
$(fuction(){
$('.btn').click(function(){
getData('myaction/getinfo', []);
})
});
function postProcessing(data){
//Put your processing logic here. e.g. Populate the data on the screen control
}
function getData(url, data) {
$.ajax({
url: url,
type: 'POST',
data: data,
error: function () {
console.log('error');
$('.custom-loader').fadeOut("slow");
},
beforeSend: function () {
$('.custom-loader').fadeIn("slow");
},
complete: function () {
$('.custom-loader').fadeOut("slow");
},
success: function (res, status) {
$('.custom-loader').fadeOut("slow");
postProcessing(res);
}
});
}

ajax request is not stopping

Here is my ajax call:
$.ajax({
url: "AutoRFQ_Vendors_ST.aspx/BindVesselGrid",
type: "POST",
timeout: 3000,
data: JSON.stringify(sendingdata),
contentType: "application/json",
success: function (data) {
//do something
}
Here is my CSS loader:
ajaxStart: function () { $body.addClass("loading"); },
ajaxStop: function () { $body.removeClass("loading"); }
When I make an ajax call which responds d:'' an empty string but my ajaxstop: event is not firing.
You have to hide your loader on ajax() complete like:
ajax({
complete: function(){
$body.removeClass("loading");
}
});
complete executes after either the success or error callback were executed.
You need to understand that the ajaxStart and the ajaxStop events falls under global event handlers in jQuery. Hence you need to hook them to document instead of having in your $ajax call.
You need to rewrite your code as,
$(document)
.ajaxStart(function () {
$body.addClass("loading");
})
.ajaxStop(function () {
$body.removeClass("loading");
});
Hope this helps!

Ajax - All request are Done/Completed

I have a difficulty to know when all Ajax requests are completed because I need this information to call another function.
Difficulty are to know when my 4/5 function with requests are completed. I use native function of ajax and none is working for me.
I used Chrome, and async requests.
Someone Helps me
I use this(not work):
$(document).ajaxStop(function() {
alert("Completed");
});
and this (not Work):
$(document).ajaxComplete(function() { alert("Completed"); });
Both ways I try use in another function thal calls all requests:
Example:
function Init()
{ Search("123"); Search2("1234"); Search3("12345");
... }
Extract one (of 5 requests,others are very similar ) of my request:
function Search(user) {
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
success: function(response, textStatus, jqXHR) {
try {
if (response != null) {
alert("Have Data");
} else {
alert("are empty");
}
} catch (err) {
alert("error");
}
},
error: function() {
alert("error");
}
}); }
have you tried putting it in a done function? something like...
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP'
}).done(function (data) {
code to execute when request is finished;
}).fail(function () {
code to do in event of failure
});
bouncing off what Michael Seltenreich said, his solution, if i understand where you guys are going with this...might look something like:
var count = 0;
function checkCount(){
if(count == 5 ){
//do this, or fire some other function
}
}
#request one
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
}).done( function(data){
count += 1
checkCount()
})
#request two
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
}).done( function(data){
count += 1
checkCount()
})
and do it with your five requests. If that works out for you please make sure to mark his question as the answer;)
You can create a custom trigger
$(document).trigger('ajaxDone')
and call it when ever you finished your ajax requests.
Then you can listen for it
$(document).on('ajaxDone', function () {
//Do something
})
If you want to keep track of multiple ajax calls you can set a function that counts how many "done" values were passed to it, and once all are finished, you can fire the event.
Place the call for this function in each of the 'success' and 'error' events of the ajax calls.
Update:
You can create a function like so
var completedRequests= 0
function countAjax() {
completedRequests+=1
if(completedRequests==whatEverNumberOfRequestsYouNeed) {
$(document).trigger('ajaxDone');
}
}
Call this function on every success and error events.
Then, ajaxDone event will be triggered only after a certain number of requests.
If you wanna track specific ajax requests you can add a variable to countAjax that checks which ajax completed.

trigger a javascript function before on any AJAX call

Here, I have a function which needs to be called before any AJAX call present in the .NET project.
Currently, I have to call checkConnection on every button click which is going to invoke AJAX method, if net connection is there, proceeds to actual AJAX call!
Anyhow, I want to avoid this way and the checkConnection function should be called automatically before any AJAX call on the form.
In short, I want to make function behave like an event which will be triggered before any AJAX call
Adding sample, which makes AJAX call on button click; Of course, after checking internet availability...
//check internet availability
function checkConnection() {
//stuff here to check internet then, set return value in the variable
return Retval;
}
//Ajax call
function SaveData() {
var YearData = {
"holiday_date": D.getElementById('txtYears').value
};
$.ajax({
type: "POST",
url: 'Service1.svc/SaveYears',
data: JSON.stringify(YearData),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (data, status, jqXHR) {
//fill page data from DB
},
error: function (xhr) {
alert(xhr.responseText);
}
});
}
And below is current way to call function:
<form onsubmit="return Save();">
<input type="text" id="txtYears" /><br />
<input type="submit" id="btnSave" onclick="return checkConnection();" value="Save" />
<script>
function Save() {
if (confirm('Are you sure?')) {
SaveData();
}
else {
return false;
}
}
</script>
</form>
You cannot implicitly call a function without actually writing a call even once(!) in JavaScript.
So, better to call it in actual AJAX and for that you can use beforeSend property of ajaxRequest like following, hence there will be no need to call checkConnection() seperately:
$.ajax({
type: "POST",
url: 'Service1.svc/SaveYears',
data: JSON.stringify(YearData),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
beforeSend: function() {
if(!checkConnection())
return false;
},
success: function (data, status, jqXHR) {
//fill page data from DB
},
error: function (xhr) {
alert(xhr.responseText);
}
});
It reduces the call that you have made onsubmit() of form tag!
UPDATE:
to register a global function before every AJAX request use:
$(document).ajaxSend(function() {
if(!checkConnection())
return false;
});
The best way is to use a publish-subsribe pattern to add any extra functions to be called on pre-determined times (either before or after ajax for example).
jQuery already supports custom publish-subsrcibe
For this specific example just do this:
//Ajax call
function SaveData(element) {
var doAjax = true;
var YearData = {
"holiday_date": D.getElementById('txtYears').value
};
if (element === myForm)
{
doAjax = checkConnection();
}
if ( doAjax )
{
$.ajax({
type: "POST",
url: 'Service1.svc/SaveYears',
data: JSON.stringify(YearData),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (data, status, jqXHR) {
//fill page data from DB
},
error: function (xhr) {
alert(xhr.responseText);
}
});
}
else
{
// display a message
}
}
Hope i understand correctly what you mean.
UPDATE:
in the if you can do an additional check if the function is called from the form or a field (for example add an argument SaveData(element))
If you use the saveData in html, do this: "saveData(this)", maybe you should post your html as well
You can use:
$(document)
.ajaxStart(function () {
alert("ajax start");
})
.ajaxComplete(function () {
alert("ajax complete");
})
That's it!!
use
beforeSend: function () {
},
ajax method

Accurate long polling example?

I've made an function that should do an long polling and fetch live data that is being "pushed" to me. Right now I'm testing against an json object that is formatted in the way that it will look once I receive the data. It seems as it is working accurate so far. I was merely wondering what you think about it? Would you refactor it somehow or do it entirely in another way?
var url = '../../path_to_script/respondents.json';
function fetchData() {
$.ajax({
url: url,
method: 'GET',
dataType: 'json',
contentType: "application/json; charset=utf-8",
cache: false,
success: function (data) {
//parseData(data);
setTimeout(function () { fetchData() }, 5000);
console.log(data);
},
error: function (data) {
setTimeout(function () { fetchData() }, 5000)
}
});
}
Regards
This works like expected. Since you've wisely choosen to fire a setTimeout once the request returned, there can't be "overlapping" requests. That is a good thing.
Anyway, you could use jQuerys "new" deferred ajax objects which is probably a little bit more convinient.
(function _poll() {
$.getJSON( url ).always(function( data ) {
console.log( data );
_poll();
});
}());
Note: .always() is brandnew (jQuery 1.6).
Edit
Example: http://jsfiddle.net/rjgwW/6/
I suggest changing the events to:
success: function (data) {
console.log(data);
},
complete: function () {
setTimeout(function () { fetchData() }, 5000)
}
The complete event is always called after success and error. This way you will only have the setTimeout line once, which is better.
I would do some changes
Change method to type, method isn't a valid parameter for $.ajax. This is an error
Remove contentType, with dataType: 'json' is enough to have those values
Do something when there's an error. Use the error parameters if you need them. For example:
.
error: function (xhr, status, errorThrown) {
alert("There was an error processing your request.\nPlease try again.\nStatus: " + status);
}
Hope this helps. Cheers

Categories

Resources