Let code wait untill AJAX request is done - javascript

I have the following code to check if a username already exists. It uses an AJAX-request to another page, this page returns either 1 (username exists) or 0 (username doesn't exist).
function checkUsername(username,callback){
$.ajax({
url: '/check_username.php',
type: 'post',
data: {username: username},
dataType: 'json',
success : function(data){
switch(data.response){
case 0:
callback(true);
break;
case 1:
callback(false);
break;
}
}
});
};
var error; // 'undefined' for now
checkUsername('abc',function(data){
if(data == false){
// username exists
error = true;
}else{
// username does not exist
error = false;
};
});
if(error == false){
alert('username does not exist');
}else{
alert('username exists');
};
Problem
The code checks if error = true (there is an error, ie. the username exists) or error = false, but the code keeps on running. It doesn't wait until the AJAX-request in checkUsername is done. So it's always "username exists" (because error = undefined, and if-else then goes to the else-statement).
Question
How can I make sure that the code waits until the AJAX-request (the checkUsername function) is completely done before going any further.
I have a "partial" solution: When I wrap the if-else-statement that checks error = true/false in a setTimeout, it works. The problem is: How many miliseconds? I want to have it as fast as possible. 500ms? What if the AJAX-response is not done then? 1000ms? Isn't that too long?
I think there is a better solution than doing this with a setTimeout. Anyone have an idea?

if(error == false){
alert('username does not exist');
}else{
alert('username exists');
};
Currently your above code
is on top of javascript, it is always being executed whether you call your ajax or not.so put it into other function and call it after calling checkUsername().
function checkUsername(username,callback){
$.ajax({
url: '/check_username.php',
type: 'post',
data: {username: username},
dataType: 'json',
success : function(data){
switch(data.response){
case 0:
callback(true);
break;
case 1:
callback(false);
break;
}
}
});
};
var error; // 'undefined' for now
checkUsername('abc',function(data){
if(data == false){
// username exists
error = true;
}else{
// username does not exist
error = false;
};
alertMsg();
});
function alertMsg(){
if(error == false){
alert('username does not exist');
}else{
alert('username exists');
}
}

try with async: false on ajax function
async (default: true)
Type: Boolean
By default, all requests are sent asynchronously (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. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().

Set async to FALSE and it will not move until ajax request is completed.
function checkUsername(username,callback){
$.ajax({
url: '/check_username.php',
type: 'post',
data: {username: username},
dataType: 'json',
async : false,
success : function(data){
switch(data.response){
case 0:
callback(true);
break;
case 1:
callback(false);
break;
}
}
});
};
var error; // 'undefined' for now
checkUsername('abc',function(data){
if(data == false){
// username exists
error = true;
}else{
// username does not exist
error = false;
};
});
if(error == false){
alert('username does not exist');
}else{
alert('username exists');
};

I had the same problem couldn't find any way but this worked for me.
function sendAjax(){
var defObj = $.Deferred();
//my ajax code here
defObj.resolve(ajaxResponse);
return defObj.promise();
}

AJAX (and a lot of other functionality of JavaScript) works asynchonous, this means you do not wait for something to happen but rater tell JavaScript what to do when something happens. In your example you're trying to wait 'till the AJAX-Request finished but what you should do is tell JavaScript to execute your code when the request finished, this means, put the code in the callback.

Even though you have used callbacks for AJAX, the way you are checking
conditions is still asynchronous..
checkUsername('abc',function(data){
alermsg(data);
});
function alertmsg(data){
!data?alert('username does not exist'):alert('username exists');
}

Related

Should I return true/false in JQuery Ajax function?

I was wondering if my code should have return statement in my AJAX function. Here is example:
$.ajax({
type: 'POST',
url: 'Application.cfc?method=runProcess',
data: {'userID':userID},
dataType: 'json'
}).done(function(obj){
if(obj.STATUS == 200){
$('#searchMsg').addClass("success").show().text(obj.MESSAGE).delay(3500).fadeOut('slow').queue(function(){
$(this).removeClass("success").dequeue();
});
return true; //Should I keep this
}else{
$('#searchMsg').addClass("error").show().text(obj.MESSAGE).delay(3500).fadeOut('slow').queue(function(){
$(this).removeClass("error").dequeue();
});
return false; //Should I keep this
}
}).fail(function(jqXHR, textStatus, errorThrown){
alert(errorThrown);
});
As you can see I have two return statements in my function. Both will return either true or false depends on the ajax return obj. Should I keep them in my function or not? What is benefit of having them and what are the cons? If anyone can explain please let me know. Thank you!
No. Remove them. They do nothing for you. You already have the ability to know if the AJAX call succeeded or failed by which portion of your if/then in your callback function you hit.
All these statements do is send a value back to the caller that the caller then can use as it wishes and stop programmatic execution. Here, the caller is the done method call, which isn't expecting any return value and since you have the statements as the last things that will be done in the function, execution will stop anyway.
No need for this true or false if you send ajax call to check something and return server is exist they return true else false e.g Login i send ma username and password to database if exist return true than i check if ajax return true mean they user login to the system if false means user not exist but not need for true false if exist you need to open new link else give error not exist its depend on what scenario you want but not necessary to return true false its not compulsory
code example
$.ajax({
url: geturl,
type: "POST",
data:{email:email,pass:pass},
success: function (res) {
if (res == "admintrue")
{
AutoLoader("Admin Login Succeffully", "success");
var URL = $("#Afetlogin").val();
window.location.href = URL;
} else if (res == "membertrue") {
AutoLoader("Member Login Succeffully", "success");
var URL = $("#memberlogin").val();
window.location.href = URL;
}
else {
AutoLoader("Error", "error");
}
}
})

Why does validation not fail on client side but fails on server side?

Right now, I have a form with several fields and on submit, I want to check if the username is taken or not. If taken, do nothing (show validation error), if not taken, successfully proceed onto the next form.
Here's what I have done so far:
View:
var RequestCreateAccount_Submit = function () {
var res = false;
ValidationAttribute.BlankValue(true);
var form = $('form#RequestCreateAccount');
$.validator.unobtrusive.parse(form);
var res = form.valid();
var data = form.serialize();
if (res) {
$.ajax({
url: Url.getFullUrl('Account/RequestCreateAccount_Submit'),
type: 'Post',
data: data,
cache:false,
success: function (data) {
//Next Dialog
},
error: AjaxLog.HandleAjaxCallFail
});
}
return res;
}
Controller:
[AllowAnonymous]
[HttpPost]
public ActionResult RequestCreateAccount_Submit(UserAccount userAccount)
{
//Check if username is unique
if (!WebSecurity.UserExists(userAccount.UserName))
{
UserSession.AddValue(StateName.CreateOrEditAccount, "CurrentUserAccount", userAccount);
JsonResult res = Json(new { Success = true, data = "", Message = "" });
return res;
}
JsonResult jres = Json(new { Success = false, data = "", Message = "Username is already registered"});
return jres;
}
I tested it with a known username and it did hit the success=false (outside of the if statement) line and it did not go inside the if statment. So I know the validation on the server side works.
However, I am wondering why on the client side, it still success = true and the next dialog appeared. It did not fail on validation. What am I doing wrong on the client side?
The reason is that your controller does actually successfully return a result. It is just that the successful result indicates an error. While logically similar at this point, they are very different. Error is going to be reserved for actual exceptions thrown or 404 no route present type of scenarios.
You should check for the response status inside of your success callback function
dotNetFiddle Demo
$.ajax({
url: Url.getFullUrl('Account/RequestCreateAccount_Submit'),
type: 'Post',
data: data,
cache:false,
success: function (data) {
if(data.Success === false){
AjaxLog.HandleAjaxCallFail();
// this may not make as much sense though
// as the request didn't actually fail, just the action did
//TODO: code for name fail
return;//do not process next dialog
}
//Next Dialog
},
error: AjaxLog.HandleAjaxCallFail
});
The success = false of your result object doesn't means that the request failed. It stands only for data.success, nothing more. The resquest is still successful(HTTP 200), which I think is the right response code. If you return an error code like new HttpStatusCodeResult(404, "error message"); it means that your request failed, but it isn't true.
You request works whatever the result of the check is. So you may check this in your success callback, instead of the error callback:
success: function(data) {
if (data.success) {
//Next Dialog
}
else {
// error message
}
}

how to find which method is causing the error during parallel ajax call

I am using $.when to make parallel ajax call to webapi controller and it works perfectly fine. The structure is given below,
$.when(GetDataFromMethodA(),GetDataFromMethodB(),GetDataFromMethodC())
.done(function (responseFromMethodA,responseFromMethodB, responseFromMethodC) {
if (responseFromMethodA != null) {
//do some action
}
if (responseFromMethodB != null) {
//do some action
}
if (responseFromMethodC != null) {
//do some action
}
}).fail(function (xhr, textStatus, errorThrown) {
//which method raised the exception?
});
Methods:
function GetDataFromMethodA() {
var Request = {};
Request.Code = name.find(':selected').val();
return $.ajax({
url: 'api/Data/GetCurrentView',
type: 'POST',
dataType: 'json',
data: Request
});
}
similarly, I have method B and C.
QUESTION:
There are situations where any one of the method fails and based on the failing method, I need to display appropriate message to the user. When anyone of the method fails, the exception is caught in the 'fail' section. But, how to find which method raised the exception?
If you use always instead of done, you can inspect whether the request succeeded with isResolved() or isRejected(), for instance:
$.when(GetDataFromMethodA(),GetDataFromMethodB(),GetDataFromMethodC())
.always(function (responseFromMethodA,responseFromMethodB, responseFromMethodC) {
if(responseFromMethodA.isRejected()) {
console.log('A did not work!');
}
if(responseFromMethodB.isRejected()) {
console.log('B did not work!');
}
// ...etc.
});

Cant access variable inside jQuery $.post [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I went through many posts about this, but didnt find any solution working for me - cleaned up code:
$('#form-new').submit(function(e){
e.preventDefault();
$curForm = $(this);
$textbox = $( '.new-box' ,this);
window.tmp_input_ok = false;
var wasError = false;
if( $.trim($textbox.val()) == "" ){
wasError = true;
}
if( wasError ){
//possible message
} else{
var jqxhr = $.post(
$(this).attr('action'),
$(this).serialize(),
function(data, textStatus, jqXHR){
if( data=="200" ){
console.log('post OK'); //this shows in console!
window.tmp_input_ok = true;
} else{
console.log('not OK');
}
}
).fail(function() {
console.log('POST fail)');
});
}
//however, window.tmp_input_ok is false here so the textbox does not empty:
if(window.tmp_input_ok == true) $textbox.val('');
else console.log('input not ok :('); //and this is outputted to console
});
Originaly, there was just a var tmp_input_ok = false initialization and then working with the tmp_input_ok variable, but it wasnt working so I tried global window... does not work either... I am starting to be desperate.
Your if statement is executed before the call is finished.
$.post is an async call and the rest of the code continues while the post is processing
You are already using .fail(), you can add .always() if you want to execute your if statement always on completion or add it to your .success() if you only want to check it when the call succeeds, similar to this:
if (wasError) {
//possible message
} else {
var jqxhr = $.post($(this).attr('action'), $(this).serialize(), function (data, textStatus, jqXHR) {
if (data == "200") {
console.log('post OK'); //this shows in console!
window.tmp_input_ok = true;
} else {
console.log('not OK');
}
// either add it here if you only want to process it on success
if (window.tmp_input_ok == true) $textbox.val('');
else console.log('input not ok :(');
}).fail(function () {
console.log('POST fail)');
}).always(function(){ // or add it here if you always wan to execute on completion regardless of fail or success
if (window.tmp_input_ok == true) $textbox.val('');
else console.log('input not ok :(');
});
}
The reason your XHR request has an onSuccess callback is because the call is asynchronous.
Take for instance this simple bit of code:
$.get(
'/foo',
function(){
alert("data received");
}
)
alert ("End of script reached");
The success callback is set up to something that will be called when the request is successfully received, rather than when that line of code is read by the browser.
Often you'll see the "End of script reached" alert before the "data received" alert simply because a full XHR request will take over 100 milliseconds, while reading those few lines will take a fraction of that.
Code that depends on having a response for a state must be called by the callback. There's far too many ways to do this for me to go into detail.

Issues with handling http errors with jQuery AJAX webservice calls

I'm developing an jQuery application in where I've a requirement to capture HTTP errors as and when it occurs. Below is my snippet.
// Function to validate URL
function validateURL(url)
{
var pattern = new RegExp();
pattern.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
if (!pattern.test(url))
{
return false;
}
return true;
}
// Generic error handler for handling the webservice requests.
function initWebService(wstype, wsurl,jsonData)
{
// If the method parameter is not either "GET" or "POST" display an error message to the developer.
var msgValidateArgument;
var wsCallStatus;
var callbackData;
if ((arguments[0] != 'GET') && (arguments[0] != 'POST'))
{
//alert("Invalid");
//alert("You must provide a valid http method in your webservice call.");
msgValidateArgument = "You must provide a valid http method in your webservice call.";
return msgValidateArgument;
}
// Making sure whether the developer is passing the required number of parameters.
if(arguments.length < 3)
{
//alert("Some required arguments seems to be missing. Please check your webservice invocation.");
msgValidateArgument = "Some required arguments seems to be missing. Please check your webservice invocation.";
return msgValidateArgument;
}
if (!validateURL(arguments[1]))
{
msgValidateArgument = "You must provide a valid URL in your webservice call.";
return msgValidateArgument;
}
if(arguments[2] != ''){
var response=jQuery.parseJSON(arguments[2]);
if(typeof response =='object'){
//It is JSON
alert(response.toSource());
}
else{
msgValidateArgument = "The JSON data being passed is not in valid JSON format.";
return msgValidateArgument;
}
}
// Making the AJAX call with the parameters being passed. The error handler handles some of the possble http error codes as of now.
$.ajax({
type: arguments[0],
url: arguments[1],
data: arguments[2],
dataType: 'json',
async:false,
statusCode:{
404: function(){
alert('Page not found');
},
500: function(){
alert('Page not found');
},
504: function(){
alert('Unknown host');
}
},
success: function(data){
//alert('Data being returned from server: ' +data.toSource());
//alert('Data being returned from server: ' +data.toSource());
//alert(data);
callbackData = data;
}
});
return callbackData;
}
But, when I programatically change the webservice url to hold a wrong value, and upon calling the html page, I'm able to see an error message in the firebug console, but my snippet doesn't seem to be catching the error at all.
For e.g, While calling the GEONames API, I'm encountering an stating "407 Authorization required" in firebug's console.but even if I handle that status code in my error block, it is not firing.. What could be the reason?.
Don't we have any comprehensive solution for handling these HTTP errors effectively?.
I think there are a few problems with your code ... firstly how is handleError called ? because you call a method called handleError but pass nothing ... im assuming your using .ajax()
You should do it like this :
$.ajax({
statusCode: {
404: function() {
alert('page not found');
},
500: function() {
alert('server error');
}
},
success : {
alert('it working');
},
complete : {
alert('im complete');
});

Categories