manipulating local variable with a callback in JS - javascript

here's my code with jquery:
function check_hotel_exists(value, col)
{
var url = base_url + 'ajax/checkuniquehotel';
var response = false;
$.get(url, {hotelname:value}, function(data){
if (data === 'true') response = true;
});
alert((response) ? 'Hotel is Not Existing' : 'Hotel Exists');
return [response, "That hotel already exists"];
}
the value of response does not change.
How do I change the value of response with a callback from the get function? I am expecting the variable data from a server response which is either 'true' or 'false'.
Any help would be appreciated.:)

The value does not change because the ajax callback that is supposed to set response to true executes asynchronously after the check_hotel_exists function exited. A possible workaround would be to execute the ajax request synchronously by setting the async option to false.
$.ajax({
url: base_url + 'ajax/checkuniquehotel',
async: false,
data: { hotelname: value },
success: function(result) {
if (result === 'true') response = true;
}
});
Another workaround is to perform the call asynchronously but in this case all the work has to be done in the success callback, your function no longer need to return a value (for example show an error message if the hotel name already exists in the success callback). IMHO this is a better approach.

All ajax requests are asynchronous, so you can't create a function that returns something based on the result of an ajax call. You should handle the response asynchronously (for example: change a piece of text on the page after the ajax call completed):
function check_hotel_exists(value, col)
{
var url = base_url + 'ajax/checkuniquehotel';
$.get(url, {hotelname:value}, function(data){
var msg = (data === 'true') ? 'Hotel is Not Existing' : 'Hotel Exists';
$("#resultmsg").text(response);
});
}

Try this
function check_hotel_exists(value, col)
{
var url = base_url + 'ajax/checkuniquehotel';
var response = false;
$.get(url, {hotelname:value}, function(data){
if (data === 'true') response = true;
alert((response) ? 'Hotel is Not Existing' : 'Hotel Exists');
//this wont work, so do something else!!!!
//return [response, "That hotel already exists"];
});
}

A solution would be to make your check_hotel_exists function asynchronous in its turn, i.e. receiving a function as a callback parameter:
function check_hotel_exists(value, col, callback)
{
var url = base_url + 'ajax/checkuniquehotel';
var response = false;
$.get(url, {hotelname:value}, function(data){
if (data === 'true') response = true;
if (callback) {callback.call(response);}
});
}
This way you can call it wherever you want to check the presence of a hotel like this:
check_hotel_exists(value, col, function(response){
alert(response);
});

Dirty approach, but it works:
Have your variable defined outside callback function:
var response = false;
function check_hotel_exists(value, col)
{
var url = base_url + 'ajax/checkuniquehotel';
response = false;
$.get(url, {hotelname:value}, function(data){
if (data === 'true') response = true;
});
alert((response) ? 'Hotel is Not Existing' : 'Hotel Exists');
return [response, "That hotel already exists"];
}

Related

Get data back from ajax call within ajax call

I'm need some help figuring out how to get back data from the second ajax call, not the first.
I have this method that calls my ajax calls
var projectWithIssues = getProjects().done(function(result) {
....
}
When I look at the results from this, I get back the results on my first ajax call(getEnt_PodType().done()). I want to get the results from the second ajax call within getProjects(). I understand the reason I'm getting the first results back is because I have the return on the first ajax call. However, If I don't have a return there. I get a undefined on the line above. How can I return the data from the second call?
function getEnt_PodType() {
var ent_PodType;
var oDataUrl = //URL to my data;
return $.ajax({
url: oDataUrl,
type: "GET",
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("ACCEPT", accept);
},
success: function (xhr, textStatus) {
}
});
}
function getProjects() {
return getEnt_PodType().done(function (res) {
var ent_PodType;
if (res.d.results != undefined) {
ent_PodType = res.d.results[0].Ent_PodType;
}
console.log("The ent pod type value is " + ent_PodType);
var QUERY_FILTER =
"$filter=Ent_PodType eq '" + ent_PodType + "'";
var url = restUrl + QUERY_FILTER;
// I want to return the results from this ajax call
$.ajax({
url: url,
type: "GET",
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("ACCEPT", accept);
},
success: function (xhr, textStatus) {
//projects = parseODataResultTest(xhr);
//return projects;
}
});
});
}
Thanks in advance!
Try utilizing pattern found at deferred.then
// first request
var request = $.ajax(url1),
chained = request.then(function( data ) {
console.log(data) // first request response data
// return second request
return $.ajax(url2)
});
chained.then(function( data ) {
console.log(data) // second request response data
// data retrieved from url2 as provided by the first request
});
var request = $.ajax("https://gist.githubusercontent.com/guest271314/23e61e522a14d45a35e1/raw/62775b7420f8df6b3d83244270d26495e40a1e9d/ticker.json"), // first request , `html` document
chained = request.then(function( data ) {
console.log(data) // `["abc"]`
// return `data` from second request
return $.ajax("https://gist.githubusercontent.com/guest271314/6a76aa9d2921350c9d53/raw/49fbc054731540fa68b565e398d3574fde7366e9/abc.txt")
});
chained.then(function( data ) {
console.log(data) // `abc123`
// data retrieved from url2 as provided by the first request
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Use .then instead of .done, it allows better chaining of functions.
Break your code apart so that the two AJAX calls are in separate functions, and have both those functions return the result of their $.ajax call. You can then use:
func1().then(func2).then(...);
func2 will be passed the result of the first AJAX call, and then the result of that will be passed to whatever function is in the final then.
In your case you can also put the call to parseODataResultTest in the chain and then the final function will (eventually) be called with the required data, i.e.:
getEnt_PodType().then(getProjects).then(parseODataResultTest).then(function(projects) {
// use projects here, and _only_ here because it won't
// be in scope or defined anywhere else
...
});

Javascript value changes outside jquery.post

I have a weired bug that is driving me crazy for some time now. I have the following piece of code:
function isLoggedIn() {
var loggedIn = false;
var requestData = {
action: 'explore-webdesign-is-loggedin',
request_url: location.protocol + '//' + location.host + location.pathname,
async: false,
data: null
};
jQuery.post(ajaxurl, requestData, function(data) {
var dataObj = JSON.parse(data);
if (dataObj.success === true) {
loggedIn = true;
alert("1.) " + loggedIn);
}
});
alert("2.) " + loggedIn);
return loggedIn;
};
Javascript spitts out both alerts, which is fine, however the first one says '1.) true' while the second one gives me '2.) false'. What is going on?
AJAX requests are asynchronous - your final alert is being executed while the AJAX is in progress - the first alert finishes once the AJAX is done (hence why it's in the callback).
You don't return from an async method like you are trying to do, instead you would pass a callback function in to be executed once the AJAX is done:
function isLoggedIn(callback) {
...
...
jQuery.post(ajaxurl, requestData, function(data) {
...
...
if (dataObj.success === true) {
loggedIn = true;
callback(loggedIn);
}
});
}
Then call like so:
isLoggedIn(function(data) {
if (data) //user is logged in
});

JS Ajax function not setting variable value

I have a simple ajax function
function get_country(request_term) {
var country_list = '';
$.ajax({
url : "activity/get_country",
type : "POST",
cache : false,
data : {
request_term : request_term
},
success : function(data) {
if(data != '') {
country_list = $.parseJSON(data);
alert(country_list); ----> Got value here
}
}
});
alert(country_list); ----> Not getting value here
return country_list;
}
the problem is, i'm getting the data in the success function, but unable to return it from the main function.
Because ajax is asynchronous, you can't know when the success function will complete (or if it will ever complete). Therefore any code that requires the result of the ajax call must depend on the ajax callback too.
jQuery makes it very easy to bind additional callbacks.
return $.ajax({ /* rest of your code */
get_country(request_term).done(function (data) {
//are you sure JSON isn't returned already?
country_list = $.parseJSON(data);
});
You can do it by making async as false. But it is not a recommented way.
This code will return country_list
function get_country(request_term) {
var country_list = '';
$.ajax({
url : "activity/get_country",
type : "POST",
cache : false,
async : false,
data : {
request_term : request_term
},
success : function(data) {
if(data != '') {
country_list = $.parseJSON(data);
alert(country_list);
}
}
});
alert(country_list);
return country_list;
}

Javascript variable scope hindering me

I cant seem to get this for the life of me. I cant access the variable "json" after I calll the getJson2 function. I get my json dynamically through a php script, and that works. But then its gone. there is a sample that I use as a guide at The InfoVis examples where the json is embedded in the init function. i am trying to get it there dynamically.
<script language="javascript" type="text/javascript">
var labelType, useGradients, nativeTextSupport,animate,json;
function getJson2()
{
var cd = getParameterByName("code");
$.get("tasks.php?code="+cd, function(data){
return data;
})
};
function getParameterByName(name)
{
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.search);
if(results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
(function() {
var ua = navigator.userAgent,
iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
typeOfCanvas = typeof HTMLCanvasElement,
nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
textSupport = nativeCanvasSupport
&& (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
//I'm setting this based on the fact that ExCanvas provides text support for IE
//and that as of today iPhone/iPad current text support is lame
labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
nativeTextSupport = labelType == 'Native';
useGradients = nativeCanvasSupport;
animate = !(iStuff || !nativeCanvasSupport);
})();
debugger;
var Log = {
elem: false,
write: function(text){
if (!this.elem)
this.elem = document.getElementById('log');
this.elem.innerHTML = text;
debugger;
this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px';
}
};
function init(){
json = getJson2();
//init data
var st = new $jit.ST({
//id of viz container element
injectInto: 'infovis',
//set duration for the animation
duration: 800,
//set animation transition type ..................
function getJson2()
{
var cd = getParameterByName("code");
$.get("tasks.php?code="+cd, function(data){
return data;
})
};
getJson2() doesn't return anything. The callback function to $.get() returns something, but nothing is listening for that return.
It sounds like you want synchronous loading instead. $.get() is just shorthand for this $.ajax() call: (See docs)
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
And $.ajax() supports more features, like setting async to false.
$.ajax({
url: "tasks.php?code="+cd,
async: false,
dataType: 'json',
success: function(data) {
// data !
}
});
Which means, getJson2 then becomes:
function getJson2()
{
var cd = getParameterByName("code");
var jsonData;
$.ajax({
url: "tasks.php?code="+cd,
async: false,
dataType: 'json',
success: function(data) {
jsonData = data;
}
});
return jsonData;
};
var myJsonData = getJson2();
Or still use $.get async style, and use callbacks instead.
function getJson2(callback)
{
var cd = getParameterByName("code");
$.get("tasks.php?code="+cd, function(data){
callback(data);
});
};
getJson2(function(data) {
// do stuff now that json data is loaded and ready
});
The $.get call is asynchronous. By the time you call return data;, the function has already long since returned. Create a variable outside of your function's scope, then in the $.get callback handler, assign data to that variable.
var json;
function getJson2(){
// ...
$.get(...., function(response){
json = response;
}
});
Alternatively, you could do a sychronous Ajax call, in which case returning your data would work (but of course would block script execution until the response was recieved). To accomplish this, see the asynch argument to jQuerys $.ajax function.
A jQuery $.get call is asynchronous and actually returns a promise, not the data itself.
An elegant way to deal with this is to use the then() method:
$.get(...).then(function(data){...});
Alternately, change your ajax settings to make the call synchronous.
$.get("tasks.php?code="+cd, function(data){
return data;
})
$.get is asynchroneous. So your value is never returned. You would have to create a callback.
The same question appears here:
Return $.get data in a function using jQuery

Let the $.post function return the response in the parent function

I got this code:
function server_request(module,section,action,data) {
data['module'] = module;
data['section'] = section;
data['action'] = action;
var responsetxt = null;
$.post('../application/server.php', data, function(data) {
responsetxt = data;
});
return responsetxt;
}
And it return's null ?
What i want is let the server_request function return the responseText?
But at some way it doesn't work, why? And how to let it work?
You're providing a callback function to $.post, which will be run when the request is returned. The server_request function returns immediately (i.e. before the response is available) so responsetxt will still be null.
To get around this you could add a callback parameter to server_request, then execute it in the anonymous function you provide to the $.post call:
function server_request(module,section,action,data,callback) {
data['module'] = module;
data['section'] = section;
data['action'] = action;
$.post('../application/server.php', data, function(data) {
callback(data);
});
}
You could then use this like:
$(function() {
var module = x, section = y, data = z;
server_request(module, section, data, function(response) {
$('#result').html(response); // do stuff with your response
});
});
Check out continuation passing style for more information ( http://en.wikipedia.org/wiki/Continuation-passing_style and http://matt.might.net/articles/by-example-continuation-passing-style/).
You could get the return value, but only when doing a synchronous call instead of an asynchronous one:
function server_request(module,section,action,data,callback) {
data['module'] = module;
data['section'] = section;
data['action'] = action;
responsetxt = $.ajax({
"url": '../application/server.php',
"async": false,
"type": "POST",
"data": data
}).responseText;
return responsetxt;
}
Remember that a synchronous call like this freezes the browser until the server responds.

Categories

Resources