This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
see I have code like this
function validate(){
if (document.getElementById('<%=txtSeqNo.ClientId %>').value.trim() == "") {
alert('Please enter Seuenceqnumer.');
return false;
}
var result = checkduplicateseq();
if (result) {
return true;
}
else {
return false;
}
}
and definitation for checkduplicateseq is
function checkduplicateseq() {
var result = true;
if ($('[id*=ctl00_CPHMainPageLambda_chkoperationlist] input[type="checkbox"]:checked').length > 0) {
var seqNo = $("#ctl00_CPHMainPageLambda_txtSeqNo").val();
var chkvalue = $('[id*=ctl00_CPHMainPageLambda_chkoperationlist] input[type="checkbox"]:checked').parent().parent().find("span").attr("datavalue");
var hfmode = $("#ctl00_CPHMainPageLambda_hd_SequenceNo").val();
var oldoperationid = $("#ctl00_CPHMainPageLambda_hd_operationo").val();
if (seqNo == "") {
}
else {
$.ajax({
type: "POST",
url: "frmFAQMst.aspx/GetSequenceNoforOperation",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: '{"OptionaId":"' + chkvalue + '","oldoperationid":"' + oldoperationid + '","seqNo":"' + seqNo + '","hfmode":"' + hfmode + '"}',
error: function (ex) {
console.log(ex);
},
success: function (response) {
if (response.d == "1") {
alert("Sequence Number already exist!");
$("#ctl00_CPHMainPageLambda_txtSeqNo").attr('value', '')
$("#ctl00_CPHMainPageLambda_txtSeqNo").focus();
result = false;
}
else {
result = true;
}
}
});
}
}
return result;
}
now if i call checkduplicateseq from validation function at the last
and store return value of checkduplicateseq fucntion in variable like
var result = checkduplicateseq();
in browser i can see the value of result = undefine
so it goes to else part of that function
if (result) {
return true;
}
else {
return false;
}
and in it return false so further execution not work
i want to go further after finishing checkduplicateseq (ajax call)
use a callback in your success function. you can pass the callback into your checkduplicateseq function, or just leave it in the global namespace and call it directly from your success function, or you can just inline that function altogether (defined inside success function)
checkduplicateseq(someCallback);
function someCallback () {
return !!result
}
and your success function
success: function(response) {
if (response.d == "1") {
alert("Sequence Number already exist!");
$("#ctl00_CPHMainPageLambda_txtSeqNo").attr('value', '')
$("#ctl00_CPHMainPageLambda_txtSeqNo").focus();
result = false;
} else {
result = true;
}
someCallback();
}
The best way, if you're chaining lots of callbacks, is to research Promises, which allow you to write in a sequential fashion, rather than passing things to be invoked later
You can add the option of async: false to the $.ajax() function which will cause the process to wait. This is generally considered bad practice though.
e.g.
$.ajax({
async: false,
type: "POST",
url: "frmFAQMst.aspx/GetSequenceNoforOperation",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
.... etc
I was checking on this issue i just found a similar question in stack overflow. Please check this link
How to do sequential asynchronous ajax requests with given number of streams
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
i'm having a problem here, in the success method of AJAX i have a if to see if the Streamer is live or not, if is live it returns "online.png" and if is not it returns "offline.png", my problem is that the returns give "undefined" but if i uncomment the console.log in console i can see "offline.png" or "online.png" on console (but the returns still giving undefined).
Someone already pass this problem?? Thanks
function checkOnline(nombre){
try {
$.ajax({
type: 'GET',
url: 'https://api.twitch.tv/kraken/streams/' + nombre,
headers: {
'Client-ID': '
},
success: function(data) {
// console.log(data["stream"]);
if (data["stream"] == null) {
return "offline.png";
break;
// console.log("offline.png");
}else {
return "online.png";
break;
//console.log("online.png");
}
},
error: function(data){
alert("Stream not found!");
}
});
} catch (e) {
alert("Conection error, try later... Monkeys are fixing it");
}
}
There is no need for return or break in this context. Nothing can be returned in an asynchronous request and you are not in an iteration, so there is nothing to break out of.
The function checkOnline is always going to return undefined, because it is an asynchronous call, it can not break out and return the result of the request.
If you want to do something with the data, you can do it directly within the callback method.
You can make something like that:
function checkOnline(nombre, callback){
try {
$.ajax({
type: 'GET',
url: 'https://api.twitch.tv/kraken/streams/' + nombre,
headers: {
'Client-ID': ''
},
success: function(data) {
// console.log(data["stream"]);
if (data["stream"] == null) {
callback("offline.png");
break;
// console.log("offline.png");
}else {
callback("online.png");
break;
//console.log("online.png");
}
},
error: function(data){
alert("Stream not found!");
}
});
} catch (e) {
alert("Conection error, try later... Monkeys are fixing it");
}
return result;
}
Actually now you return value from success function, not from checkOnline function. You can provide a callback for process result of async call of ajax function.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I have an AJAX function that is called from a javascript function.
Something like this:
(CODE1)
//javascript function calling AJAX.
var function check(){
var status = chkHoliday(date,'Date Chosen');
alert('called');
return status;
}
//AJAX function
function chkHoliday(date,str){
var flag = true;
$.ajax({
type: "GET",
url: someurl,
async: false, //if commented, the alert() from the caller function is called before completion of this function.
dataType: "json",
success: {
flag = false;
}
});
return flag;
}
It works well. The only problem is that since async it is set to false, the web page sort of hangs for a while but then continues to proceed further.
To avoid this I read something about callback functions so i tried this out:
(CODE 2)
//javascript function calling AJAX.
var function check(){
var status;
chkHoliday(date,'Date Chosen',function(retVal){
status = retVal;
});
if(status != null){
alert(status);
return status;
}
else{
alert(true);
return true;
}
}
//AJAX function
function chkHoliday(date,str,callback){
var flag = true;
$.ajax({
type: "GET",
url: someurl,
//async: false, //if commented, the alert() from the caller function is called before completion of this function.
dataType: "json",
success: {
flag = false;
callback(flag);
}
});
//return flag;
}
this worked but the alert was called again before the AJAX function could complete stating "undefined". I don't know what I'm doing wrong.
I want, that the AJAX function should wait till it executes completely and then return to the calling function and run the next statements in the caller function with halting the process (i.e with the use of async). Also i want that the value returned by AJAX should be easily accessible to my caller function.
Put the alert inside the callback function:
chkHoliday(date,'Date Chosen',function(retVal){
status = retVal;
if(status != null){
alert(status);
}
else{
alert(true);
}
});
But note you cannot use the return statement anymore as what you have expected because it is asynchronous.
Since AJAX works asynchronous, it is a problem to place it in a function and return a value. To solve this use deferred with a promise. This will promise the ajax result to the caller. It is slightly different. Here is an example. Works like a charm for me.
Of course you will need to adapt it to your needs, but all you really have to do is create your data object.
var data = {}
function chkHoliday(data) {
var deferred = $.ajax({
method: "post",
url: ajaxURL,
dataType: "json",
data: data
});
return deferred.promise();
}
chkHoliday(data).done(function (response) {
console.log(response);
}
return from your php file with a
echo json_encode(array("success"=>"hello"));
Put the alert inside the callback
functions. or else alerts will work simultaneously inspite of success or error.
I have this code..
if (!checkIfCustomerIsValid(event)) {
event.preventDefault();
return false;
}
else {
AddCustomer();
}
function checkIfCustomerIsValid(event) {
if ($('#txtCName').val() == '') {
alert('Please enter a valid value for customer name!');
return false;
}
if ($('#txtCAddress').val() == '') {
alert('Please enter a valid value for customer address!');
return false;
}
}
It returned fine, until then, but I added a new check and its not returning anything.
function checkIfCustomerIsValid(event) {
// code that was already there, the name and address check
var _mobNo;
if ($('#txtMobile').val() == '') return false;
var _unq = $.ajax({
url: '../Autocomplete.asmx/IsMobileUnique',
type: 'GET',
contentType: 'application/json; charset=utf8',
dataType: 'JSON',
data: "mobileNo='" + $('#txtMobile').val() + "'",
async: false,
timeout: 2000,
success: function (res) { if (res.d) return false; else return true; },
error: function (res) { alert('some error occurred when checking mobile no'); }
}),chained = _unq.then(function (data) { if (data.d == false) { alert('mobile no already exists!'); $('#txtMobile').focus(); return false; } return true; });
}
If mobile no is not unique the alert shows fine that mobile no is not unique, but when it is unique the code doesn't go into AddCustomer (in the else part)??? Is it not returning true? Why is it not going into AddCustomer???
With your new test, checkIfCustomerIsValid is asynchronous. There is no way for it, even with deferred, to directly return the result of a distant call.
The simplest here would be to pass a callback to your checkIfCustomerIsValid function or to return the promise from the function. As you mix synchronous and asynchronous tests, the best would be to pass a callback to checkIfCustomerIsValid.
You're correct, there is not a scenario where checkIfCustomerIsValid would return true. This is because you're attempting to return true from an anonymous function (i.e. a callback after the ajax request). When you return true from
chained = _unq.then(function (data) { if (data.d == false) { alert('mobile no already exists!'); $('#txtMobile').focus(); return false; } return true; });
You're only returning from that anonymous function, not from checkIfCustomerIsValid. Solving this problem is not completely straight forward and is an issue created from the nature of asynchronous calls. The most common solution to this is to pass a callback to your asynchronous call. Here is a fiddle which implements this.
http://jsfiddle.net/p3PAs/
Ajax is asynchronous and won't block, so the return value is most likely undefined. You can modify the code to something like the following:
success: function (res) { if (res.d) callRoutineToAddCustomer(); },
I want to call three functions someTask1, someTask2 and someTask3 in that order. However, the function someTask2 involves Ajax call, and keep calling itself recursively using setTimeout unless a desired value is return. The code looks like this:
doListOfTasks: function(myparam){
var someObj = someTask1(myParam);
someTask2(someObj);
someTask3(someObj);
},
someTask2: function(someObj){
$.ajax({
url: "someUrl.do",
type: "POST",
data: ({"id": rowObject.instanceId}),
dataType: "json",
async:false,
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj);}, 2000);
}
}
}
);
},
As you might have guessed, the execution of this code does not wait for someTask2 to return before calling someTask3.
I want the code inside doListOfTasks to be executed sequentially. How can I do that?
Also, I do not want to hard-code someTask3 in success callback. E.g. I do not want to do this:
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj);}, 2000);
}else{
someTask3(someObj);
}
}
How can achieve this?
Thanks
Edit#1
The problem is not being able to call the functions... but the problem is synchronization. I want someTask2 to finish whatever it's doing, and only then someTask3 is called.
someTask2 calls itself repetitively using setTimeout... I guess this triggers a new thread and someTask2 is returned after first call... triggering someTask3 in main thread. However, separate thread spawns (and gets killed) in each call setTimeout until the desired criteria is met.
That's why, while the someTask2 still looping, the call to someTask3 triggers.
Not sure how correct I am.
You can achieve this using a Deferred in jquery:
$.when(someTask1(), someTask2(), someTask3()).then(successFunc, errorFunc);
You need to return a custom made .Deferred object with a promise value.
someTask2: function(someObj)
{
var def = $.Deferred();
$.ajax({
url: "someUrl.do",
type: "POST",
data: ({"id": rowObject.instanceId}),
dataType: "json",
async:false,
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj);}, 2000);
}
else
{
def.resolve(res);
}
}
}
);
return def.promise();
}
So for example:
function someTask1()
{
var def = $.Deferred();
def.resolve('i\'m data resolved from task1');
return def.promise();
}
function someTask2(someObj)
{
var def = $.Deferred();
var count = 0;
var f = function() {
console.log(++count);
if (count > 2) {
def.resolve('whoop we got the value we wanted in task 2 after many tries: ' + count);
}
else
setTimeout(f, 1000);
};
f();
return def.promise();
}
function someTask3()
{
var def = $.Deferred();
def.resolve('and hello from task3!');
return def.promise();
}
var success = function(x) {
console.log('success:', arguments);
};
var error = function() {
console.log('oh no an error occured in one of the tasks.');
};
$.when(someTask1(), someTask2(), someTask3()).then(success , error);
Will show
1
2
3
success: ["i'm data resolved from task1",
"whoop we got the value ...k 2 after many tries: 3",
"and hello from task3!"]
fiddle available: http://jsfiddle.net/garreh/29SW7/
You could pass a callback to someTask2. For example:
someTask2: function(someObj, callback){
$.ajax({
url: "someUrl.do",
type: "POST",
data: ({"id": rowObject.instanceId}),
dataType: "json",
async:false,
success: function(res){
if(res.prop1 != 'desired'){
setTimeout(function(){someTask2(someObj, callback);}, 2000);
} else {
if (callback != null) {
callback();
}
}
}
}
);
}
Then just pass someTask3 as the callback:
someTask2(someObj, function (){ someTask3(someObj); });
I want to assign value to global variable in javascript from jquery ajax function.
var trueFalse;
$.ajax({
type: "GEt",
url: "url",
data: "text=" + $("#text").val(),
success: function(msg) {
if(msg.match(/OK/) != null) {
trueFalse = "true";
}
else {
trueFalse = "false";
}
}
});
return trueFalse;
here i need the value of trueFalse from success function.
thanks
v.srinath
Your code won't work because the line return trueFalse; executes before the success function runs, since it is called as the result of an asynchronous (as in the A in Ajax) HTTP request. You would need to pass in a callback function to this code, and invoke that in the success function:
function getWithCallback(val, callback) {
var scope = this;
$.ajax({
type: "GET",
url: "url",
data: "text=" + val,
success: function(msg) {
callback.call(scope, msg.match(/OK/) || false);
}
});
}
getWithCallback($("#text").val(), function(result) {
if (result) {
// Do something
}
});
You could try this to validate a form on submit:
var validating = false;
var valid = false;
$('#myform').submit(function(event) {
if (validating) {
return false;
}
if (valid) {
return true;
}
var form = this;
validating = true;
getWithCallback($('#text').val(), function(result) {
if (result) {
valid = true;
form.submit();
}
validating = false;
});
return false;
});
You might also want to look at the jQuery Validation plugin
If you really can't change the application logic, then you have to create a "synchronous" ajax request (by setting async:false in $.ajax options), then it will wait until the "GET" has executed and only then return the value to the caller.
Otherwise, you should rewrite the code so that the success function calls back into some callback function that it can now proceed with whatever has to be done.
Since you are doing this on form.onsubmit, you cannot do an async request. The browser won't know that it should wait until the async request is finished. The benefit of using async is that it does not lock up your scripts/browser, but in this case that is actually what you want.