Preventing Ajax save data two times - ajax

Whenever I run Ajax in jquery, it will run two times. It will cause a problem in saving data. I googled and used their metods but none of them worked. The following is the ways I tried:
Set a global flag. Set it on when Ajax is running, turn it off after done. It seems that duplicated calls manage the flag concurrently. Before call 1 closed the door, call 2 is already in in no time. Or check time if less than 4000, do not run Ajax.
Generating a random number and attach to the url, they are the same always.
event.preventPropgador();e.preventDefault(); does not work in whichever order
async:true or false does not work
I cannot use "once" since I am usimg jQuery Mobile
$("#submitButton").once("tap", function () { //<-- error
save();
});
used "one" but not work
$("#submitButton").one("tap", function () {
save();
});
disable the button when ajax running, then enable it afterwords.
I tried above techs on save() and Ajax calls, none of them worked.
This is my code like:
$(document).bind("pageinit", function () {
$("#submitButton").one("tap", function () {
save();
});
}
function save() {
$.ajax({method: "get",
url: baseUrl + "save?model=abcd&rand=" + randonNum(),
contentType: "application/json; charset=utf-8",
success: function (response) {
//do whatever
}
},
error: function (request, status, error, errorThrown) {
}
});
}

Related

What does an asynchronous AJAX call return?

I am trying to create a test case to monitor progress of multiple parallel asynchronous server tasks. I have the code sort-of working, but there are several pieces I don't understand. First, what does the $.ajax call below return? In theory, it should return undefined, but that doesn't seem to be the case.
function doParallel() {
var promiseA, promiseB, handleSuccess, handleFailure;
var dataA = JSON.stringify({ size: a });
var dataB = JSON.stringify({ size: b });
promiseA = $.ajax({
url: testGlobal.urlA,
data: dataA,
type: "POST",
async: true,
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (rtnData) {
// Get the result
result = (rtnData === undefined) ? null : $.parseJSON(rtnData.d);
},
error: function (xhr, textStatus, errorThrown) {
// Whoops! didn't work
reportAjaxError(xhr, textStatus, url, data);
},
complete: function (xhr, textStatus) {
// Errors have already been handled, so only
// deal with success cases
}
}); <--- WHAT GETS RETURNED TO PROMISE HERE?
... (same code for promiseB, etc.
var notifyingPromiseA = intervalPromise(2000, 'a');
var notifyingPromiseB = intervalPromise(2000, 'b');
...
promiseA.done(function() {
log("A done");
}
promiseB.done(function() {
log("B done");
}
$.when(promiseA, promiseB).done(function() { log ("All done") });
}
function intervalPromise(millis, source) {
var deferred = $.Deferred();
//checkProgress();
log("Checking progress on " + source);
var id = setInterval(function () {
deferred.notify();
if (testGlobal.aDone && testGlobal.bDone) {
clearInterval(id);
deferred.resolve();
}
}, millis);
return deferred.promise();
}
...
$.ajax() returns the XMLHttpRequest object. As of jQuery v1.5, $.ajax() also implements and returns a Promise / Deferred interface.
http://api.jquery.com/jQuery.ajax/
http://api.jquery.com/category/deferred-object/
With a Promise, you can chain additional callbacks based on the results of the original ajax call.
// setup interval / timer to update UI not finished / still working logic
$.ajax().done(function() {
// clear UI not fninshed / still working logic
});
mmm.. official docs say:
The $.ajax() function returns the XMLHttpRequest object that it
creates. Normally jQuery handles the creation of this object
internally, but a custom function for manufacturing one can be
specified using the xhr option. The returned object can generally be
discarded, but does provide a lower-level interface for observing and
manipulating the request. In particular, calling .abort() on the
object will halt the request before it completes.
http://api.jquery.com/jQuery.ajax/
As of jQuery 1.5, jQuery.ajax() (and various ajax shortcut methods) returns a jqXHR object, which is a superset of the browser's native XMLHttpRequest object and implements inter alia the Promise interface.
Read more about the jqXHR object here.

How to stop AJAX calls if there's an error on a field with a keyup trigger

I have this jquery ajax call that is trigger on keyup. It has error handling which (with Firefox for e.g.) is triggered multiples times if the user enters keystrokes fast. Is there a quick way to stop multiple alert windows to be shown?
$('input[name$="_LOC"]').keyup(function(){
if ($(this).val().length >=4){
$.ajax({
type: 'POST',
url: 'red.asp?q='+$(this).val(),
beforeSend: function() {
[...]
},
success: function(data) {
[...]
},
error: function() {
alert("Oops!")
}
});
}
});
Restart a timer each time the onkeyup is triggered, this means the event only happens when the user has finished typing (or, at least, paused for a second or whatever).
Use timer = setTimeout(yourFunction, yourDelay);
To rest the timer user clearInterval(timer) and start the setTimeout again.
var typing = false;
var timer;
$('input[name$="_LOC"]').keyup(function(){
if(typing) {
clearInterval(timer);
}
timer = setTimeout(sendAjax, 500, [this]);
typing=true;
});
function sendAjax(element)
{
if ($(element).val().length >=4){
$.ajax({
type: 'POST',
url: 'red.asp?q='+$(element).val(),
beforeSend: function() {
[...]
},
success: function(data) {
[...]
},
error: function() {
alert("Oops!")
}
});
typing = false;
}
Here's JSFiddle example: http://jsfiddle.net/X8US5/, you'll need your browsers console.log viewer ready to see stuff (otherwise edit the console.logs to be alerts though they interrupt JS so times will be off)
Edit:
IE9 compatible (hack) version http://jsfiddle.net/5ndM5/1/
Tried to find a jQuery alternative but none it seems.
THe overriding the function alternative is good if you don't want the global var, but if you only plan to use this code on one form then the global is acceptable (JS code is usually rife with them by accident anyway)

jQuery - AJAX request using both native XHR and flXHR (Flash) fallback - how to minimize code duplication?

I need to retrieve data via cross-domain XMLHttpRequest. To make this work in (almost) all browsers, I use native XHR first and, if that fails, flXHR.
The (working) code I currently have for this is as follows:
jQuery.support.cors = true; // must set this for IE to work
$.ajax({
url: 'http://site.com/dataToGet',
transport : 'xhr',
success: function(data) {
console.log('Got data via XHR');
doStuff(data);
},
error: function(xhr, textStatus, error) {
console.log('Error in xhr:', error.message);
console.log('Trying flXHR...');
$.ajax({
url: 'http://site.com/dataToGet',
transport : 'flXHRproxy',
success: function (data) {
console.log('Got data via flXHR');
doStuff(data);
},
error: function (xhr, textStatus, error) {
console.log('Error in flXHR:', error.message);
console.log('Both methods failed, data not retrieved.');
}
});
}
});
This feels like a lot of code duplication to me, especially in the success handlers. Is there a more efficient way to do this? I'd really prefer to make one $.ajax call that would try both transports in turn, instead of having to use the error handler to make the call a second time. It's not too bad in this example, but rapidly gets more complicated if the success handler is longer or if the success handler has to itself issue another $.ajax call.
I've created a jquery-specific and slimmed-down fork of flxhr that simplifies your code sample above. You can see an example of usage in the "Usage" section in the README.
https://github.com/b9chris/flxhr-jquery-packed
In particular, you don't want to waste time waiting for a standard CORS request to fail. It's easy to determine whether flxhr is necessary by testing $.support.cors upfront (no need to override it). Then just use flxhr explicitly where necessary.
Why don't you just wrap this in a function by itself? That's after all, how you end up reusing code. You can even pass functions as arguments to make sure that you don't have to repeat this code more than once.
To me this is pretty straight forward but maybe I've misunderstood.
function xhr(success) {
$.ajax({
success: success,
error: function() {
$.ajax({ success: success })
}
});
}
Then just pass the success handler once
xhr(function(data){/*magic*/});
Or if you wanna basically avoid redundant configuration of the ajax call use the first object as a template, like this:
function xhr(success) {
var ajaxParams = { success: success };
ajaxParams.error = function() {
$.ajax($.extend(ajaxParams, { transport: 'xhr' }));
}
$.ajax(ajaxParams);
}
I simplified the whole thing a bit, but I hope you get the point.
Edit
Reading that last bit, maybe this will give you some ideas... it's a variation of that last snippet.
function xhr(success) {
var ajaxParams = { success: success };
ajaxParams.error = function() {
var newParams = $.extend(ajaxParams, { transport: 'xhr' });
newParams.success = function() {
// do something
// arguments is a special array, even if no parameters were
// defined in any arguments where passed they will be found
// in the order they were passed in the arguments array
// this makes it possible to forward the call to another
// function
success.apply(this, arguments);
}
$.ajax(newParams);
}
$.ajax(ajaxParams);
}

Dojo addOnUnload and xhrGet

I have function to unlock data sets via an API
function unlockData() {
var xhrArgs = {
url: "/api/unlockData",
handleAs: "json",
content: {
account_id: accountId
},
load: function(data) {
if(data) {
alert("Data unlocked");
} else {
alert("Something went wrong.");
}
},
error: function(error) {
alert("error:"+error);
}
}
var deferred = dojo.xhrGet(xhrArgs);
}
which is called onUnload
dojo.addOnUnload(window, "unlockData");
When reloading, this I get this error message:
Error: Unable to load /api/unlockData?account_id=981782 status:0
Can I fire an xhrGet request on unload at all? BTW, the function works fine, if not called on unload.
Since Xhr calls are asynchronous, putting this call during the 'Unload' will fail always because the browser is not in this page anymore.
Anyways, since the addOnUnload is triggered during the window.onbeforeunload, you can put a "timer" loop to check if the AJAX call has success.
I strongly don't recommend this practice. Using an AJAX call during the "window" closing is totally unnecessary, you should consider to use a form instead and call your scripts synchronously

load doesn't trigger ajaxSetup complete handler on complete

I have
// Ajax setup
$.ajaxSetup({
beforeSend: function() {
$('#general-ajax-load ').fadeIn();
},
complete: function() {
$('#general-ajax-load ').fadeOut();
}
});
on page load to set loading animation for all my ajax calls. It works perfect, except for load() calls. For loads only beforeSend is triggered, and complete never gets called, Which results with showing animation which never dissapears.
Any idea?
According to http://bugs.jquery.com/ticket/4086#comment:4, the "correct" way would be:
$(document).ajaxSend(function(event, jqXHR, settings) {
$('#general-ajax-load ').fadeIn();
});
$(document).ajaxComplete(function(event, jqXHR, settings) {
$('#general-ajax-load ').fadeOut();
});
I just did some testing and that indeed seems to work in all cases (including $.load).
Adding success fixed the problem, thanks (I can swear I tried it before)
$.ajaxSetup({
beforeSend: function() {
$('#general-ajax-load ').fadeIn();
},
complete: function() {
$('#general-ajax-load ').fadeOut();
}
success: function() {
$('#general-ajax-load ').fadeOut();
}
});
:)
The $.load manual says:
...It is roughly equivalent to
$.get(url, data, success) except that
it is a method rather than global function and it has an implicit
callback function.
It would seem that $.load's implicit callback function is overriding the complete callback in your $.ajaxSetup. The $.ajaxSetup documentation says:
All subsequent Ajax calls using any
function will use the new settings,
unless overridden by the individual
calls, until the next invocation of
$.ajaxSetup().
I guess the solution would be to replace your $.load calls with $.get (or the more verbose $.ajax). You could also try using success instead.

Resources