assign value to global variable in javascript - javascript

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.

Related

how to stop function processing until the ajax call complete? [duplicate]

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

javascript function inside jquery foreach loop doesn't wait for response

My foreach loop:
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
if(deleteQuoteItemFromListing(jQuery(this).attr('data-id'))){
console.log('passed');
}else{
console.log('failed');
}
}
});
And the function is(It's using prototype) but it successes
function deleteQuoteItemFromListing(id){
//does someoperations and on success
delurl = getDelUrl()+id; //baseurl/module/action/delete/id
new Ajax.Request(delurl,{
method: 'get',
onSuccess: function(transport){
return TRUE;
}
})
}
but the problem is all foreach executes at once, and doesn't wait for response from function. It prints failed even the operation is success.
Updated
The other way round i tried first is this
jQuery('.delete-from-quote').click(function() {
var i = 0, j = 0;
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
i++;
}
});
if (i == 0) {
alert('please choose product');
return false;
}
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
var urlData = "<?php echo $this->getUrl('qquoteadv/index/delete/'); ?>";
urlData += "id/" + jQuery(this).attr('data-id') + "/"
var ajax = jQuery.ajax({
type: "GET",
url: urlData,
success: function(msg) {
j++;
}
})
}
if(i==j){location.reload();} //after completing all, reload the page
});
});
The problem is to know all action completed and reloading the page.
My guess is that the code you've omitted is doing an asynchronous ajax call. Since ajax is asynchronous by default, the code you write there ($.ajax or whatever) starts the process, but then the process continues in the background while your code continues to run.
There's no reasonable way to make the deleteQuoteItemFromListing function wait for the response. (While it's possible to do synchronous ajax, A) it makes for a poor user experience by locking up the browser UI, and B) jQuery will be removing that option at some stage, forcing you to go direct to XHR if you want to keep doing it.)
Instead, restructure your code to embrace the asynchronous nature of web programming by having your function either return a promise or accept a callback, and then resolve the promise or call the callback when done.
Here's a rough idea of what the promise version would look like:
jQuery(".custom-checkbox").each(function() {
if (jQuery(this).attr('data-action') == 'true') {
deleteQuoteItemFromListing(jQuery(this).attr('data-id'))
.done(function(id) {
console.log(id + ' passed');
})
.fail(function(id) {
console.log(id + ' failed');
});
}
});
function deleteQuoteItemFromListing(id){
var d = jQuery.Deferred();
jQuery.ajax(/*...*/)
.done(function() { // This bit assumes the deletion worked if
d.resolveWith(id); // the ajax call worked, and failed if the
}) // ajax call failed; if instead the ajax
.fail(function() { // call always works and returns a flag,
d.rejectWith(id); // adjust accordingly
});
return d.promise();
}
Using callback ensures that the function is executed.
jQuery(".custom-checkbox").each(function () {
if (jQuery(this).attr('data-action') == 'true') {
deleteQuoteItemFromListing(jQuery(this).attr('data-id'), handleData);
}
});
function handleData(data) {
if (data) {
console.log('passed');
} else {
console.log('failed');
}
}
function deleteQuoteItemFromListing(id, callback) {
//does someoperations and on success
delurl = getDelUrl() + id; //baseurl/module/action/delete/id
new Ajax.Request(delurl, {
method: 'get',
onSuccess: function (transport) {
callback(true);
}
})
}
I hope this will work for you. you need to define handleData function outside of the other function.
Use jquery When.
You need to queue those Deferred in an array of Deferred and then apply all of the functions at once.
If one fails all will fail and if all succeeds all will pass.
check this out jQuery When
var queue = [];
var items = 0;
return new $.Deferred(function (deferred) {
$(".custom-checkbox").each(function () {
if ($(this).attr('data-action') == 'true') {
items++;
queue.push(function () {
new Ajax.Request(delurl, {
method: 'get',
onSuccess: function (transport) {
items--;
if(items === 0)
deferred.resolve();
},
onError:function(e){
deferred.reject(e);
}
});
});
}
});
//now resolve all of the deferred fns
$.when(queue).done(function(){
console.log('All went well');
})
.fail(function(e){
console.log('Error ' + e);
});
});
(Part of) Your problem is in this simple statement:
return TRUE;
In JavaScript, the "true" boolean is written in lowercase:
return true;
The interpreter thinks TRUE is a variable, and will throw a ReferenceError, since it's not set / defined anywhere, meaning the function will never return true.

Wait until multiple functions, which may or may not call ajax internally, are complete in jQuery?

I am currently validating a few inputs clientside. When the user submits the form, I want to check the values for the form inputs, and then do something once all the checks are complete
$('form').submit(function() {
var input1 = $('form #input1');
var input2 = $('form #input2');
//validate both input values
validate_input(input1);
validate_input(input2);
//wait until all validation complete to execute code here
return false;
});
Here, the "validate_input" function will check the input value. If it passes the initial checks (such as character length), then it will make an AJAX request for further validation (ex. checking if username is taken). Something like this:
function validate_input(input){
value=input.val();
if (value.length<4){
//code to execute if input is too short
}
else {
$.ajax({
type: 'get',
url: check_input_url,
data: input.serialize(),
success: function(data){
if (data=="invalid") {
//code to execute if invalid
} else {
//code to execute if valid
}
}
});
}
}
I am currently using jQuery.when() and .done() functions, but the done() function does not wait until all the validate_input functions are completely done (including AJAX callbacks called from validate_input)
$.when(
validate_input(input1),
validate_input(input2)
).done(function(){
//code here
});
How would I wait until all the validate_input functions are complete (finished with any possible AJAX callbacks), before executing further code?
I don't see you validate_input function return anything. If you want to wait, you need to return a promise, so that you don't pass undefined to $.when():
function validate_input(input){
var value=input.val();
if (value.length<4){
return …; //code to execute if input is too short
} else {
return $.ajax({
// ^^^^^^
…
});
}
}
var inputsLength = 0, // or maybe set it to $('form input').length
inputsReady = 0;
function checkInputsValidation(){
if (++inputsReady === inputsLength) YOURSALLINPUTSAREVALIDFUNCTION();
}
function validate_input(input){
inputsLength++; // remove it if you already set inputsLength
// blablabla
$.ajax({
type: 'get',
url: check_input_url,
data: input.serialize(),
success: function(data){
if (data=="invalid") {
//code to execute if invalid
} else {
checkInputsValidation();
}
}
});
}
UPDATE: i just updated my answer. it is more likely to fit your needs now. i've added a parameter to the callback function.
use callbacks with anonymous functions and chain them:
1. add a parameter for the callback function and the callback function call:
function validate_input(input, callback){
value=input.val();
if (value.length<4){
//code to execute if input is too short
callback(false);
}
else {
$.ajax({
type: 'get',
url: check_input_url,
data: input.serialize(),
success: function(data){
if (data=="invalid") {
//code to execute if invalid
callback(false);
} else {
//code to execute if valid
callback(true);
}
}
});
}
}
2. when calling your function multiple times, chain it with anonymous functions (which are executed after success in your $.ajax-request has been fired):
$('form').submit(function() {
var input1 = $('form #input1');
var input2 = $('form #input2');
//validate both input values
validate_input(input1, function(result){
if(result == true)
{
validate_input(input2, function(result){
if(result == true)
{
//wait until all validation complete to execute code here
}
else
{
return false;
}
});
}
else
{
return false;
}
});
});

JQUERY AJAX WITH CALLBACK [duplicate]

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.

jquery ajax deferred object not returning value

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

Categories