Dojo addOnUnload and xhrGet - ajax

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

Related

Preventing Ajax save data two times

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) {
}
});
}

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)

First ajax call on Phonegap + Zepto returns undefined even after device ready

I'm doing a jsonp call in my mobile app at startup to connect to my server. I'm using Phonegap 2.1 and Zepto 1.0-rc1. At the bottom of my html page, I do the init stuff on DOM ready.
<script type="text/javascript">
if (!$) {$ = Zepto};
$(init);
document.addEventListener('deviceready', Perksea.deviceReady);
</script>
...
function init() {
var router = new Backbone.Router();
...
}
function deviceReady() {
isConnected();
isConnected();
}
function isConnected() {
$.ajaxJSONP({
url: 'http://localhost/isconnected',
success: function(response) {
console.log('response is ' + response);
}
});
}
The first JSONP call will print "response is undefined" but the second JSONP call works. I've even tried putting the JSONP call in a setTimeout(isConnected, 5000) with the same result. Have already checked that the url is correct etc.
Has anyone seen something like this?
Thanks
Steve
since you are getting into the "success" callback function on the first call (where response is undefined), are you sure that your server is properly responding to the first call? Sounds like it is returning a 200 response, but with no data for that first call.
You can try adding an 'error' callback to see if that provides anything useful as well
$.ajaxJSONP({
url: 'http://localhost/isconnected',
success: function(response) {
console.log('response is ' + response);
}
error: function(response) {
console.log('error is ' + response);
}
});
Finally, because AJAX is Asynchronous, your 2 calls to isConnected() are going to fire one immediately after the other, not waiting for the first to respond. I'm curious what it looks like on the server side (see above).

Alert is coming before response

I have this ajax function which validates the user provided key. but the alert comes before the ajax response and due to which if the user provide a wrong key even can get access
$(document).ready(function() {
$('#submit').click(function(e) {
e.preventDefault();
var key = $('#downloadkey').val();
var dataString = {KEY:key};
$.ajax({
url: "/mediabox/home/validate_key",
type: 'POST',
data: dataString,
success: function(msg) {
if(msg=="true")
{
alert("do something");
}
else
{
alert("Your download key is either wrong or you didn't provide it.");
return false;
}
}
});
});
});
What makes you believe the alert is coming before the response? The success handler is only invoked after the response has been successfully received client-side.
To confirm, you can edit your success handler to log the response:
success: function(msg) {
console.log(msg);
if(msg=="true")
{
alert("do something");
}
else
{
alert("Your download key is either wrong or you didn't provide it.");
return false;
}
}
Also, if you're using the return false to deny access to the user by blocking the HTML action that, won't work due to the asynchronous nature of AJAX.
The success function is called when the request completes.
success(data, textStatus, jqXHR)Function, Array
A function to be called if the request succeeds. The function gets passed three
arguments: The data returned from the server, formatted according to
the dataType parameter; a string describing the status; and the jqXHR
(in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the
success setting can accept an array of functions. Each function will
be called in turn. This is an Ajax Event.
The code within the success handler will only execute once the AJAX request is completed. If you are getting an alert before hand then that indicates that the request completed properly.

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);
}

Resources