OK, So I am creating a entire web app using AJAX with some local storage etc.
The issue I am having is sometimes I double click, or click tabs back and forth quickly which invoke a $.post call.
Problem lies when the callbacks are fired, they are called back and keep overwritting eachother until the last call has came back.
Obviously that is a problem. What I need to do is cancel current POST calls and just get the last callback.
I have tried:
// Make Call:
if(call != undefined){
call.abort();
}
var call = $.post(url,{do:'stuff'},function(response){
// callback stuff:
},'json');
Keeps saying its undefined regardless, I rather use .POST than .AJAX if possible.
Thanks for your help in advance!
Simply unbind the click event on click, re-bind it on callback.
One thing you can do if canceling doesn't catch all your pending XHRs: increment a counter and pass it to your backend to keep old responses from clobbering new ones. Just have your backend include the counter value in the response, and then your callback can compare it to the local counter before overwriting.
Related
Working on a platform, to enable auto-ticketing functionality. For which a REST API request is used for ticket creation. Unfortunately, there are 2 requests popping simultaneously, which results in creating duplicated tickets.
How to handle such case and send only one of these requests?
Tried adding the 2nd request in the response callback of the first, though this does not seem to work.
if (flag == 1){
logger.debug("Node-down alarm-Request raised - +sitn_id);
clearTimeout(mouseoverTimer);
mouseoverTimer = setTimeout(function(){
logger.debug("Inside Call back function - ");
//function call for ticket creation
incidentRequest(sitn_id,confUtil.config.mule_url);
}, 10);
You really should show more of the code that makes the request, though it seems as if you are doing some ajax inside your 'incidentRequest', so I will presume that (if that isn't what you are doing, then please, show your code....) - and since you tags say javascript and jquery - well, here goes...
To stop the 'double send' in an AJAX call, it is simple:
function incidentRequest(sitn_id,confUtil.config.mule_url){
// stop the double by clearing the cache
$.ajaxSetup({cache: false});
// continue on with the AJAX call
// presuming the url you want is confUtil.config.mule_url
// and the data you want to send is sitn_id
$.post(confUtil.config.mule_url, 'sitn_id=' + sitn_id, function (data) {
// do cool stuff
});
}
Hopefully that will help you get moving. If not, then we will need more code of what is going on around all this.
i am trying to display the data fetched from database in the loop and between loop i call the function and send ajax request its not working.Actually its displays the only if i used alert command. If i used alert then the browser display the div and then alert if i clicked ok then it displays the second div then again show alert.
Here is the js code
function like(divid,id,session) {
var orgnldiv=document.getElementById(divid);
var ndiv=document.createElement('DIV');
var idd=id+5000;
ndiv.id =idd;
ndiv.className="likeclass";
orgnldiv.appendChild(ndiv);
var dynamicdiv=document.getElementById(idd);
var span=document.createElement('span');
var spanid=idd+5000;
span.id=spanid;
span.className="spanclass";
dynamicdiv.appendChild(span);
var xmllhttp15;
if (window.XMLHttpRequest) {
xmlhttp15=new XMLHttpRequest();
} else {
xmlhttp15=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp15.onreadystatechange = function() {
if (xmlhttp15.readyState==4 && xmlhttp15.status==200) {
document.getElementById(spanid).innerHTML=xmlhttp15.responseText;
}
}
xmlhttp15.open("GET","spancount.php?postid="+id+"&userid="+session);
xmlhttp15.send();
// alert(spanid);
}
please suggest me what can be the reason of this problem my code is working well only if i use alert
The reason why your code works when you use alert is because whenever the alert function is called. The program flow is paused. In other words, your loop wont continue to make another Ajax call until you dismiss the alert.As a result, the request gets handled properly and the response data appears in the span div. that is why I had mentioned to make your calls synchronous instead.
So to answer the question you asked in the comment, Yes at times too many Ajax calls can be a problem. Let's say that the loops runs more than 15-20 times, that means 15-20 simultaneous requests. Now, think about the number of times the same request is being handled by the php script? Definitely a problem here!
Even with Jquery Ajax, the chances of the loop completing successfully is also 50-50 actually because it all boils down to the amount of requests being made , the bandwidth being used and how the request is being processed at the server.
One possible way to fix this problem is : Rather than constantly requesting small peices of data again and again from the server in the loop, Make one Ajax call and get the entire data as json. Then, parse the json and append data to the spans by using the particular span id to extract the relevant data from the json object.
You might have to do a little bit of tweaking in both the above javascript and spancount.php . But it will definitely Save you A LOT of bandwidth. You gotta consider the fact that more than one person could be using your site!!
Hope that cleared up things, all the best with your project :D
I'm experiencing some extremely weird behavior with Ajax. Or maybe it's normal. I wouldn't know. I'm quite new to playing around with Ajax.
My problem is that I am making a few Ajax calls(two using $.post() and one using the standard $ajax() call), and they seem to return the data fine, but the code inside the success function only works in a very peculiar way.
I have noticed that some things work if placed first in line to be executed; but why is that? It really doesn't make any sense to me. In this case I would like the span with the id link_span to be updated dynamically, as my Ajax calls link and unlink devices from each other.
(the correct_classes function counts how many links have been linked and adds it to the link_counter variable that I've made global with the window object).
But as the span only wants to update if the corresponding code is placed on top, it's kinda useless.
Another problem is also that .ajaxComplete() and other such event handlers don't always get called. For example, I attempted to show and hide a loader gif by using .ajaxComplete() to close it when ajax stop. But this only works with one of my calls which is the standard $.ajax call.
I'm really confused.
Any help would be great, and please ask me to clarify if there's something I haven't made clear enough.
Here is a small snippet of what I'm talking about:
$.post( "<?php echo base_url(); ?>connections/ajax_link", datax).done(function( resp,status ) {
$("#loader_overlay").css('display','none');
display_confirmbox();
resp=JSON.parse(resp);
var str = resp['parent_selector'];
var arr = mystr.toString().split("||");
correct_classes(arr[1], resp);
$( '#link_span' ).text( '( ' + window.link_counter + ' ) links found' ); //this doesnt work unless its on top
});
Update
It seems that the problem is caused by correct_classes();
the array from the ajax call gets passed to the function in which jQuery complains about something, and causes the rest of the ajax code to halt. Yet everything inside correct_classes() gets executed. The error in question is this:
TypeError: invalid 'in' operand e
specifically what is causing the problem seems to be this(i commented everything else out and this is:
$.each( val, function( i, value ) {
var mystr = value;
}
I really cant figure out why it complains about this code when it seems to work.
i'm not sure to have understand your problem.... but if you use 3 async ajax call ($.post or $.ajax is indifferent $.post is a contract syntax to call $.ajax({type:"post"})) you need to wait the full loading of all calls for use their response.
so.. if one of your call evalue window.link_counter you need to wait his response before call the code you have post.
For wait the complete load you may nast the call inside the success function of the prev call.
for you knowlage there is an attribute of $.post() dataType if you set it to "json" you not need to parse the response because Jquery do it for you, this code is useless:
resp=JSON.parse(resp);
and, the method .done() is calling whether the call is successful if it fails, $.post() has a success function callback. Use it, it's better, and use .fail() to catch call error.
See documentation about $.post(): here
however... the element who have this id #link_span is generated by one of ajax call?
Any way to stop the code execution and then resume it? For example, next code will not run until a flag value is changed and then resume it.
Edit: I have a code that starts a loop of AJAX requests and I need to control (with a flag if its possible) thats loop when the user visits other tabs of the browser to stop it. Then, when the user returns to the application, loop would resume.
The problem would be solved with setInterval to AJAX requests and a flag to stop them. But I think that is more correct to do the loop of AJAX requests from the success ajax function, i.e. when the response is done, because I am using a MVC pattern and have the ajax function in a model and the called is done from de view. And then, the loop with setIntervalwould start in a wrong side
however, I am thinking that "setInterval" could be in the AJAX called function
You can detect when the browser tab becomes inactive using any of many methods (I'm fond of using JQuery to set focus and blur events on the document, but there are other techniques), but I think the pattern you're looking for is the "closure that sets its own new timeout on completion" instead of setInterval.
var active = true;
function myloop()
{
if (active)
{
$.ajax(/*...*/).done(function(j)
{
/* do stuff */
window.setTimeout(myloop, interval);
});
}
}
In this scenario you'll need to set active = true and call myloop() again when you detect the tab or window becoming active again. When the tab becomes inactive, set active = false. The currently running AJAX request will complete safely; but further requests won't be made until you manually restart the loop.
I have a php script that outputs json data. For the purposes of testing, i've put sleep(2) at the start.
I have a html page that requests that data when you click a button, and does $('.dataarea').append(data.html)
(php script returns a json encoded array. data.html has the html that i want to put at the end of <div class="dataarea">...HERE</div>.
The trouble is, if i click the button too fast (ie. more than once within two seconds (due to the sleep(2) in the php script)), it requests the php file again.
how can i make it only do one request at a time?
i've tried this (edited down to show the important parts):
amibusy=false;
$('#next').click('get_next');
function get_next() {
if (amibusy) {
alert('requesting already');
}
else {
amibusy=true;
// do the request, then do the append()
amibusy=false;
}
}
but this doesn't seem to work. i've even tried replacing the amibusy=true|false, with set_busy(), and set_not_busy(). (and made a function am_i_busy() { return amibusy; })
but none of this seems to work. what am i missing?
If you're in jQuery the amibusy would be jQuery.active which contains a count of currently active AJAX requests, like this:
if(jQuery.active > 0) { //or $.active
alert('Request in Progress');
}
Keep in mind that in jQuery 1.4.3 this becomes jQuery.ajax.active.
Disable the button in the click event and enable it again when the request is finished. Note that the request is asynchronous (i.e. "send request" returns immediately), so you must register a function that is called when the answer comes in.
In jQuery, see the load() function and the success method plus the various AJAX events which you can tap into with ajax().
I'm wondering about your "do request" logic. Whenever I've done calls like this they've always been asynchronous meaning I fire the request off and then when the response comes another function handles that. In this case it would finish going through that function after setting the callback handler and set your value of amibusy back to false again before the request actually comes back. You'd need to set that variable in the handler for your post callback.
Could you use the async variable?
http://api.jquery.com/jQuery.ajax/
asyncBoolean Default: true
By default, all requests are sent
asynchronous (i.e. this is set to true
by default). If you need synchronous
requests, set this option to false.
Cross-domain requests and dataType:
"jsonp" requests do not support
synchronous operation. Note that
synchronous requests may temporarily
lock the browser, disabling any
actions while the request is active.