how to break execution and display error inside success of ajax? - javascript

I am using ajax call to check for some validation and then submitting the form normally by html. In my ajax call,
function checkId() {
var str = $("#formObj").serialize();
$.ajax({
type : "post",
data : str,
url : "checkForId.mt",
async : false,
success : function(txt) {
if (txt == "pass") {
return "true";
} else if (txt == "same") {
$("#errorMsgIdSame").removeClass("hidden");
return "false";
}
},
error : function() {
alert("Error");
}
});
}
If the control goes to "pass", execution should continue. If it goes to "same", the execution should stop.
I am calling this ajax method from some other method.
function validateForm() {
var isValid = true;
isValid = checkId();
if (!isValid) {
$("#errorMsg").removeClass("hidden");
}
return isValid;
}
this validatioForm is called on button click. Now ajax code is working but validateForm method is not taking the return of the ajax method.
Need direction on how to carry this out so that to capture the return from the ajax method and how to return from the ajax method.

If I understood your question correctly, you want to return the result of an inner function from an outer function. This definition of checkId does just that.
function checkId() {
var result;
var str = $("#formObj").serialize();
$.ajax({
type : "post",
data : str,
url : "checkForId.mt",
async : false,
success : function(txt) {
if (txt == "pass") {
result = true;
return;
} else if (txt == "same") {
$("#errorMsgIdSame").removeClass("hidden");
result = false;
return;
}
},
error : function() {
alert("Error");
}
});
return result;
}

An ajax call is asynchronous.
When you call ajax what is happening is that the ajax starts a new thread to do its task--a post in your case.
After that the code that called the ajax keeps going.
When the task that the ajax call is doing returns, it executes what ever is in its pass or fail sections depending on the task status.
So basically your checkId method completes and returns before the ajax is finished.
I would recommend triggering whatever you need the return value for from the success section or fail section like this:
success : function(txt) {
if (txt == "pass") {
newfunction(true);
} else if (txt == "same") {
$("#errorMsgIdSame").removeClass("hidden");
newfunction(false);
}
},
Edit:
function newfunction(passFail)
{
//Do something with variable passFail
}

Related

Wait for AJAX response before moving on with script

I have a script which runs 2 AJAX calls, the first checks that a record exists within a database. If it does this should not move on and the script should stop. The second submits a job.
My problem is that the job is being submitted before the first AJAX call has returned. My code looks something like this:
if (recordid) {
var request = $.ajax({
context: document.body,
url: URLGOESHERE,
data: {
recordID: recordid
},
success: function( data ){
if (data.Response == "Success") {
var noresults = data.Results;
if (noresults > 0){
alert('this record id already exists!');
return false;
}
} else {
alert('an error occured');
return false;
}
}
});
} else {
alert('enter a record id');
return false;
}
// second ajax call goes here, which gets called regardless of the output of the ajax call above
Instead of putting the call to the second ajax method at the bottom of your code (where the comments currently are), put it in the "success" function of your first call. This method will only execute once the first call has finished. This is the only way to ensure that the second call does not happen too early. Ajax calls run asynchronously, so the normal flow of the browser is not interrupted. This is deliberate so that long-running calls don't lock up the browser for the user.
if (recordid) {
var request = $.ajax({
context: document.body,
url: URLGOESHERE,
data: {
recordID: recordid
},
success: function(data) {
//check here if you want to call submitJob or not
//and call submitJob()
}
});
} else {
alert('enter a record id');
return false;
}
//call this ajax once you varified your condition from success callback of first one
function submitJob() {
//second ajax call goes here
}
You have to use jquery promise function for that which will wait for the first ajax request to complete then make another ajax request.
JQUERY PROMISE
OR
Put the second ajax request in the success function of first one, and make it happen when you want it to fire
if (recordid) {
var request = $.ajax({
context: document.body,
url: URLGOESHERE,
data: {
recordID: recordid
},
success: function(data) {
//check here if you want to call submitJob or not
if (noresults > 0){ return false }
else { Job(); };
}
});
} else {
alert('enter a record id');
return false;
}
function Job() {
//another ajax call.
}
Hope it helps :)
try this: make async propety false
if (recordid) {
var request = $.ajax({
context: document.body,
url: URLGOESHERE,
data: {
recordID: recordid
},
async : false, //added this
success: function( data ){
if (data.Response == "Success") {
var noresults = data.Results;
if (noresults > 0){
alert('this record id already exists!');
return false;
}
} else {
alert('an error occured');
return false;
}
}
});
} else {
alert('enter a record id');
return false;
}
OR
perform second ajax call in success function of first ajax call i.e. see comment
if (recordid) {
var request = $.ajax({
context: document.body,
url: URLGOESHERE,
data: {
recordID: recordid
},
success: function( data ){
if (data.Response == "Success") {
var noresults = data.Results;
if (noresults > 0){
alert('this record id already exists!');
return false;
}
//perform 2nd ajax call here
} else {
alert('an error occured');
return false;
}
}
});
} else {
alert('enter a record id');
return false;
}

Waiting for a get request to complete

Alright, so I am making something that will make an account. I have this function that checks if the username exists, and if it isn't it returns false.
Then I have another function calling it, but it is automatically going to the else statement and not waiting for the get request to complete. How would I make it wait until it gets a response?
var accountPassword = "accToGetTix"
function checkUsername(username){
$.get("http://www.roblox.com/UserCheck/DoesUsernameExist?username=" + username, function(data){
$( document ).ready(function() {
return data.sucess; // true = taken , false = not taken
});
});
};
function makeNewAccount(accountName){
if (checkUsername(accountName) == false){
signupWindow = window.open("http://www.roblox.com/login/signup.aspx");
signupWindow.$("#SignupUsername").val(accountName)
signupWindow.$("#SignupPassword").val(accountPassword)
signupWindow.$("#SignupPasswordConfirm").val(accountPassword)
signupWindow.$('#birthdayMonthSelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayDaySelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayYearSelect option[value="25"]').prop('selected', true)
signupWindow.$('.gender-circle').click();
} else {
return true; // true = account taken , false = not taken
}
}
makeNewAccount('asdf205m0');
You can achieve this by updating your code like following
function checkUsername(username, callback) {
$.get("http://www.roblox.com/UserCheck/DoesUsernameExist?username=" + username, function(data) {
callback(data.sucess); // true = taken , false = not taken
});
};
function makeNewAccount(accountName) {
checkUsername(accountName, function(response) {
if (response == false) {
signupWindow = window.open("http://www.roblox.com/login/signup.aspx");
signupWindow.$("#SignupUsername").val(accountName)
signupWindow.$("#SignupPassword").val(accountPassword)
signupWindow.$("#SignupPasswordConfirm").val(accountPassword)
signupWindow.$('#birthdayMonthSelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayDaySelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayYearSelect option[value="25"]').prop('selected', true)
signupWindow.$('.gender-circle').click();
} else {
return true; // true = account taken , false = not taken
}
});
}
You can't return from an async call. You need to use callbacks. A little refactor and you can make it work:
function checkUsername(username, callback){
$.get("http://www.roblox.com/UserCheck/DoesUsernameExist?username=" + username, function(data){
if (callback) callback(data.sucess); // true = taken , false = not taken
});
};
function makeNewAccount(accountName){
checkUsername(accountName, function(response) {
if (response === false) {
signupWindow = window.open("http://www.roblox.com/login/signup.aspx");
signupWindow.$("#SignupUsername").val(accountName)
signupWindow.$("#SignupPassword").val(accountPassword)
signupWindow.$("#SignupPasswordConfirm").val(accountPassword)
signupWindow.$('#birthdayMonthSelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayDaySelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayYearSelect option[value="25"]').prop('selected', true)
signupWindow.$('.gender-circle').click();
} else {
return true; // true = account taken , false = not taken
}
})
}
you will have to use the .done function, like that:
var accountPassword = "accToGetTix"
function checkUsername(username){
$.get("http://www.roblox.com/UserCheck/DoesUsernameExist", {
"username": username
}).done(function(data){
if (data.success) {
alert("this username already exists");
} else {
makeNewAccount(username);
}
});
};
function makeNewAccount(accountName){
if (checkUsername(accountName) == false){
signupWindow = window.open("http://www.roblox.com/login/signup.aspx");
signupWindow.$("#SignupUsername").val(accountName)
signupWindow.$("#SignupPassword").val(accountPassword)
signupWindow.$("#SignupPasswordConfirm").val(accountPassword)
signupWindow.$('#birthdayMonthSelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayDaySelect option[value="0"]').prop('selected', true)
signupWindow.$('#birthdayYearSelect option[value="25"]').prop('selected', true)
signupWindow.$('.gender-circle').click();
} else {
return true; // true = account taken , false = not taken
}
}
you can find more information here: https://api.jquery.com/deferred.done/
I'm not sure about what your get call returns, so, if you'll have to adapt your code if needed. Use console.log(data), inside the .done function if needed too. :p
EDIT:
the $.get function in jQuery makes an Assynchronous http request to the specified URL. Assynchronous means that the code will not necessarily run in a linear order by waiting the request to complete in order to pass to the next code line.
The javascript code can be categorized in two types: Synchronous and Assynchronous. Let me show you an example.
This is a synchronous code:
function IWillRunFirst(){
console.log("first!");
}
IWillRunFirst();
alert("I am the second");
var someElement = $("#justAnElement");
someElement.addClass("foo");
console.log("finish");
//this results:
// "first!"
// "I am the second"
// "finish"
This code will run in the exactly same order that it was wrote. Now here an example of assynchronous code:
function IWillRunFirstButMyResponseWillGetLate(){
$.get("someUrl", {
"myUrlParameter": "foo"
}).done(function(requestResponse){
console.log("Howdy! Did I got late?");
});
}
IWillRunFirstButMyResponseWillGetLate();
alert("I am the second");
var someElement = $("#justAnElement");
someElement.addClass("foo");
console.log("finished");
The result of the above code can be:
"I am the second"
"finished"
"Howdy! Did I got late?"
Remember: Ajax calls are ALWAYS assynchronous ;)
I think the cleanest way is to use promises object through jquery deffered https://api.jquery.com/jquery.deferred/, along with it u need to use jquery $.get method which returns promises. https://api.jquery.com/jquery.get/.
I can share the code examples, but going through this concept will benefit you more .

calling jquery ajax function from javascript [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jQuery ajax return value
How to return the response from an AJAX call from a function?
I have javascript. It loads data from database. I want to return true or false with respect to loading data. But I could not return it. My code has given bellow:
function CheckISRC() {
var url = "/TrackEdit/CheckISRC/" + $('#isrcid').val();
var isrc = $('#isrcid').val();
var result = false;
$.get(url, {
isrc: isrc
}, function (data) {
if (data == "true") {
result = true;
}
else {
result = false;
}
});
return result;
}
It always gives false result. Anyone has faced this kind of problem? 'Thanks advance'
If it's so important to use the function synchronously you can refactor it to:
function CheckISRC() {
var url = "/TrackEdit/CheckISRC/" + $('#isrcid').val();
var isrc = $('#isrcid').val();
var result = false;
$.ajax({
async: false,
success: function (data) {
if (data == "true") {
result = true;
}
else {
result = false;
}
},
data: { isrc: isrc }
});
return result;
}
As #ManseUK async is deprecated in jQuery 1.8 so if you want synchronous approach you should use older version.
The problem is that when you return result, It doesnt have value. because the ajax didn't finish its task. you make some callback function and when the result of ajax is returned from server, do what you want to.
Some thing like this:
function CheckISRC(Callback) {
var url = "/TrackEdit/CheckISRC/" + $('#isrcid').val();
var isrc = $('#isrcid').val();
var result = false;
$.get(url, {
isrc: isrc
}, function (data) {
if (data == "true") {
Callback(true);
}
else {
Callback(false);
}
});
}
function YourCallback(result) {
//...
}
The JQuery ajax functions are asynchronous. This means that when you initialise result to false, the result is set to true or false after the "return result;" line has run.
You can make the call synchronous but this is considered worse practice. You are often better off refactoring your code to allow for the asynchronous nature of the JQuery Ajax.
For example, where you previously had:
function myFunction() {
//Code before
var result = CheckISRC();
//Code after using result
}
you could have the following:
function myFunction() {
//Code before
CheckISRC();
}
function myFunction_callback(result) {
//Code after using result
}
where you call myFunction_callback in the success option of your ajax code like so:
function CheckISRC() {
var url = "/TrackEdit/CheckISRC/" + $('#isrcid').val();
var isrc = $('#isrcid').val();
$.get(url, {
isrc: isrc
}, function (data) {
myFunction_callback(data == "true");
});
}

What design pattern should I apply when checking multiple ajax request completion?

I have 3 ajax call in one function and checkAjaxCompletion which checks each ajax completion flag.
What the code below does is send multiple separate ajax calls and interval method checks completion flags to determine whether to proceed or keep interval. (I know clearInterval is not shown but the point is I want to use something other than interval)
Current code is:
function manyAjax() {
setInterval( function() { checkAjaxCompletion(); } , 200);
ajax1();
ajax2();
ajax3();
}
function ajax1() {
//send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}
function ajax2() {
//send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}
function ajax3() {
//send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}
function checkAjaxCompletion() {
if(ajax1_flag == 1 && ajax2_flag == 1 && ajax3_flag == 1) {
//everything went success, do some process
}
else if(ajax1_flag == 2 || ajax2_flag == 2 || ajax3_flag == 2) {
//some ajax failed, do some process
}
else {
//all ajax have not been completed so keep interval i.e. do nothing here
}
}
But I'm hesitating to depend on using interval function because calling it so often seem such waste of memory. There must be better way to do. I'm thinking if observer pattern can be applied here but would like to hear opinions.
It is observer-notifier, if you want to call it that - but each of your ajax calls will more than likely have a callback in javascript when they complete. Why not call checkAjaxCompletion() at the end of each of them, and do nothing if you're still waiting on others?
Dustin Diaz does a great job with this example.
function Observer() {
this.fns = [];
}
Observer.prototype = {
subscribe : function(fn) {
this.fns.push(fn);
},
unsubscribe : function(fn) {
this.fns = this.fns.filter(
function(el) {
if ( el !== fn ) {
return el;
}
}
);
},
fire : function(o, thisObj) {
var scope = thisObj || window;
this.fns.forEach(
function(el) {
el.call(scope, o);
}
);
}
};
The publisher:
var o = new Observer;
o.fire('here is my data');
The subscriber:
var fn = function() {
// my callback stuff
};
o.subscribe(fn);
To unsubscribe:
var fn = function() {
// my callback stuff
};
o.subscribe(fn);
// ajax callback
this.ajaxCallback = function(){
$.ajax({
type: "POST",
url: ajax.url,
data: {key: value},
async : !isAll,// false使用同步方式执行AJAX,true使用异步方式执行ajax
dataType: "json",
success: function(data){
if(data.status == 'successful'){
selfVal.parent().find('.msg').addClass('ok').html(msg.ok);
}else if(data.status == 'failed'){
checkRet = false;
selfVal.parent().find('.msg').removeClass('ok').html(msg.error);
}else{
checkRet = false;
}
return this;
}
});
}
return this;
Maybe you want to check your inputvalue callback ajax in your form;
You can view my website Demo, hope help you.
http://6yang.net/myjavascriptlib/regForm
Okay my idea was to make your own object that can handle sending an array of requests, keep a history of each request and do what i'm gonna call 'postProccessing' on each response, here is a probably very dodgy bit of code to hopefully demonstrate what I am thinking.
var Ajax = function() {
var request, callback, lst;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
request.onreadystatechange = handleResponse;
this.history = [{}];
this.send = function(args) {
for (var i = 0; i < args.length; i++) {
if (args.url) {
request.open(args.type || 'GET', args.url);
}
request.send(args.data || null);
callback = args.callback;
lst++;
}
}
function handleResponse() {
var response = {
url: '',
success: true,
data: 'blah'
};
history.push(response);
if (postProccess()) {
callback();
}
}
function postProcess() {
if (this.history[lst].success) {
return true;
} else {
return false;
}
}
}

jquery function doesn't return values correctly

I have this function
$.fn.validate.checkValidationName = function(id) {
$.post("PHP/submitButtonName.php", {checkValidation: id},
function(data) {
if(data.returnValue === true) {
name = true;
} else {
name = false;
}
**console.log("name = "+name); **//this prints out "true"****
}, "json");
};
and this .click function that calls it. All the variables are declared outside this function so that they should be accessible by other functions
$('.submitBtn').click(function() {
//clears the array before re-submitting the click function
nameValues = [];
usernameValues = [];
emailValues = [];
name = false;
username = false;
email = false;
//for each of the input tags
$("input").each(function() {
//if the curent input tag has the class .name, .userpass, or .email
if(($(this).hasClass("name"))) {
nameValues.push($(this).val());
} else if(($(this).hasClass("userpass"))) {
usernameValues.push($(this).val());
} else if(($(this).hasClass("email"))) {
emailValues.push($(this).val());
}
});
//call the checkValidation function with the array "values"
$.fn.validate.checkValidationName(nameValues);
$.fn.validate.checkValidationUsername(usernameValues);
$.fn.validate.checkValidationEmail(emailValues);
console.log("name = "+name); //but this prints out "false"
console.log("username = "+username);
console.log("email = "+email);
if((name === "true") && (username === "true") && (email === "true")) {
alert("Everything checks out great");
} else {
alert("You missed one!");
}
});
When I click the link to trigger the first function, it returns the value as "true" inside the function, but when I console.log("name"+name); in the .click function after the function call, it prints out false.
Why is this? Do I need to return something from the checkValidatoinName function?
$.post is asynchronous, which means that it won't wait for the result to get back before proceeding. You're probably initializing name to true somewhere, and it's getting true the first time, but all the other times, it's false, because the AJAX from the first one finished and set it to false.
Try using $.ajax instead of $.post, and set async to false in the options. The $.post documentation shows the options that $.post would give to $.ajax.

Categories