I'm no professional in JavaScript and I've seen searching a long time for this on the internet.
I'm having a problem getting a variable from another function. My code is looking like this:
var variabeltje;
$.post('js/ajax/handle_time.php', {'time': $(this).find('input').val()},
function(data) {
alert(data);
variabeltje=data;
}
);
alert(window.variabeltje);
The variable variabeltje must get the information from data. When I put the alert below variabeltje=data it's working, but I need the data variable after the function.
Edit:
I have changed it to what people said, I now have this:
var XHR = $.post('js/ajax/handle_time.php', {time: $(this).find('input').val()});
XHR.done(function(data) {
console.log(data);
getData(data);
});
function getData(data) {
if(data == 'true') {
alert(data);
$(this).unbind('keypress');
$(this).html($(this).find('input').val());
}
}
But now the $(this) isn't passing into the function. How can I solve this?
As it's asynchronous the data will only be available after the ajax call is completed, so you'll have to modify your code to work with that and wait until after the ajax is done to do your stuff:
var XHR = $.post('js/ajax/handle_time.php', {time: $(this).find('input').val()});
XHR.done(function(data) {
console.log(data);
});
or in other function:
function XHR(time){
return $.post('js/ajax/handle_time.php', {time: time});
}
function doStuff(element) {
XHR($(element).find('input').val()).done(function(data) {
console.log(data);
});
}
EDIT:
based on your edit, it looks like it's a scoping issue:
var self = this,
XHR = $.post('js/ajax/handle_time.php', {time: $(self).find('input').val()});
XHR.done(function(data) {
console.log(data);
getData(data);
});
function getData(data) {
if(data == 'true') { //normally you'd try to pass true as a boolean, not string
alert(data);
$(self).unbind('keypress').html($(self).find('input').val());
}
}
This is because the $.post method runs asynchronously.
Please take a look at this question on SO.
Edit: You can change your code and put the part after post method inside the body of the anonymous function triggered on success. As follows:
$.post('js/ajax/handle_time.php', {'time': $(this).find('input').val()},
function(data) {
alert(data);
variabeltje=data;
alert(window.variabeltje); // or whatever function you need to call, call it here...
}
);
The problem is that post method is executed asynchronously. This is, a post is sent to the server but execution flow continues so your alert is trying to access a value that wasn't set since post haven't returned yet.
You could use ajax method if you need a synchronic execution.
Related
I'm fairly new to AJAX, but working on a project that requires an ajax call to validate a specific value, then make another ajax call if the first returns the expected value. I am trying to implement the .done/.fail model, but can't find a way to prevent both calls from happening simultaneously, rather than once the first call is done and successful.
The following code will call the ajaxCall function twice, but concurrently rather than consecutively. I have researched a ton of code, including Nested AJAX Calls, jQuery getting rid of nested ajax functions, and $.when.done callback isn't working, but none seem to fit my exact scenario, or maybe I just don't understand the code. Either way, I haven't been able to find a solution, and any help will be much appreciated!
var xReturn = ajaxCall("1");
xReturn.done(function(msg){
console.log("callback "+msg+" successful");
// if successful, place second call
if(parseInt(msg)==1)
xReturn = ajaxCall("2");
});
function ajaxCall(mop){
return $.ajax({
url: "getItem.php",
type: "POST",
data: {code: '<?php echo $code; ?> ', op:mop}
});
}
It seems like promises may be the way to go, but I can't wrap my head around how to use them in this scenario. Thanks in advance for any pointers in the right direction.
Update:
I ran through a battery of tests with different results. For my final test last night, I placed another console.log(msg); directly after ajaxCall("2"); Each time the resulting msg was always "1", leading me to believe the calls were not happening properly. This result tells me that xReturn.done(function(msg)... is only being called once, but I thought it would be called with each ajax call.
With this new information, I will perform additional testing tonight and report back.
Thanks
You need to bind a .done() method to each promise. xReturn.done() binds a function to that promise.
When you do xReturn = ajaxCall("2");, you are replacing xReturn with a different object. This object does not have a .done() method bound to it.
You need to bind .done() to each promise, that doesn't happen automatically.
var xReturn = ajaxCall("1");
// This binds the callback to this *specific* promise
xReturn.done(ajaxDone);
function ajaxCall(mop){
return $.ajax({
url: "getItem.php",
type: "POST",
data: {code: '<?php echo $code; ?> ', op:mop}
});
}
function ajaxDone(msg){
console.log("callback "+msg+" successful");
// if successful, place second call
if(parseInt(msg)==1){
xReturn = ajaxCall("2");
// Bind a callback to this *new* object
xReturn.done(ajaxDone);
}
}
There are multiple ways to go about this problem.
You could simply call the second ajax call from the success of the first. Something on the following lines
function ajaxCall(mop){
$.ajax({
url: "getItem.php",
type: "POST",
data: {code: '<?php echo $code; ?> ', op:mop}
}).done(function(msg) {
console.log("First call is done. Received data as ", msg);
if(parseInt(msg)==1) {
$.ajax({
//Repeat Options
}).done(function(newMsg)) {
console.log("We're done");
};
}
});
}
}
If you do want to use the .done/.fail model, you could try using $.when.
Here is a working fiddle that does consecutive calls using the same function.
function ajaxCall(mop){
return $.ajax({
url: "/echo/json/",
type: "POST",
data: {
json: $.toJSON({data: mop}),
delay: Math.floor(Math.random()*4)
}
});
}
$.when(ajaxCall("1")).done(function(data) {
console.log("Done with first call. About to call second");
if(data /* and add whatever conditions you need to call the next function */) {
ajaxCall("2");
}
});
Try it like this.
ajaxCall("1");
function ajaxCall(mop){
$.post( "getItem.php", {code: '<?php echo $code; ?> ', op:mop})
.done(function( msg) {
console.log("callback "+msg+" successful");
if(parseInt(msg)==1)
ajaxCall("2");
});
}
And also you can use these with previous code
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "finished" );
How about that:
var xReturn1 = ajaxCall("1"),
xReturn2 = ajaxCall("2");
$.when(xReturn1, xReturn2).done(function( a1, a2 ) {
var data1 = a1[0], data2 = a2[0];
console.log("Both done");
});
What I'm trying to do is the following in JS:
function getSuccessForTest(testName,version,fromRev,toRev,res) {
var params = {
"methodToRun":"getSuccessForTest",
"version":version,
"startRev":fromRev,
"endRev":toRev,
"testName":testName
};
$.post("Stats.php", params,function(data){
return parseInt(data.toString(),10);
}, "json");
}
getSuccessForTest(data[i],version,fromRev,toRev,res);
What am I doing wrong ? whenever I make the call to getSuccessForTest, I get the POST result in Stats.php but the value isn't returned to the calling function.
Thanks in advance !
It's not working because the return is in the callback function given to $.post as a parameter. Since you're dealing with an ajax request which is asynchronous you need to use a callback for getSuccessForTest as well. Try this:
function getSuccessForTest(testName,version,fromRev,toRev,res, callback) {
var params = {
"methodToRun":"getSuccessForTest",
"version":version,
"startRev":fromRev,
"endRev":toRev,
"testName":testName
};
$.post("Stats.php", params,function(data){
callback(parseInt(data.toString(),10));
//return parseInt(data.toString(),10);
}, "json");
}
getSuccessForTest(data[i],version,fromRev,toRev,res, function (data) {
alert(data); // This would be the value you wanted to return
});
That's beacuse value is returned to the anonymous function (function(data){...). Use callbacks. Try this:
function getSuccessForTest(testName,version,fromRev,toRev,res, callback) {
var params = {
"methodToRun":"getSuccessForTest",
"version":version,
"startRev":fromRev,
"endRev":toRev,
"testName":testName
};
$.post("Stats.php", params,function(data){
callback(parseInt(data.toString(),10));
}, "json");
}
getSuccessForTest(data[i],version,fromRev,toRev,res, function(res) {
alert(res)
} );
use echo when you are return from stats.php. if this is not solving your issue then I would like to know what is the return method you are using for your ajax call handling script.
return parseInt(data.toString(),10);
You cant return like that.
either assign in some global variable or do process there with data
I have the following javascript code:
function initSite(){
var site;
$.getJSON(www+'init/initSite', function(data) { site = data; });
}
$(document).ready(function(){
var site = initSite();
console.log(site);
}
which returns undefined... how can i store the json object that i recieve in the site variable so i can use it later?
EDIT:
This seem to work but im not sure if its correct to use this solution
var site = null;
$.ajax({
url: www+"init/initSite",
async: false,
dataType: 'json',
success: function (data) {
site = data;
}
});
console.log(site);
of course you got undefined because your function doesn't return anything and the ajax call is also asynchronous, so you have to wait the server response. Since $.ajax (and shortcuts) returns a promise you can do this task using deferred
function initSite(){
return $.getJSON(www+'init/initSite');
}
$(document).ready(function(){
$.when(initSite()).done(function(data) {
/* continue here the code execution, e.g. call another function */
doAllTheRemainingWorkWith(data)
});
}
as you can see this code is short and easy to read
function initSite(onSuccess){
$.getJSON(www+'init/initSite', onSuccess);
}
$(document).ready(function(){
initSite(function(data){
var site = data;
// initialize your code.
});
}
The problem is just a miss concept:
getJSON is an async call, and the site = data; will only happen way after the DOM is ready.
in order for you to make everything work the way it should, your initialization needs to start from your async call result and never before, for example:
// no need to wait for DOM ready to call `initSite`
initSite();
function initSite() {
$.getJSON(www+'init/initSite', function(data) {
initialization(data);
});
}
function initialization(site) {
// initialize all the things that need to be done
console.log(site);
}
$(document).ready(function(){
// do other stuff, for example show a loading message/image
}
I need to get a variable from inside the GET request and use it inside the function. It's not working. Here is my code:
function chooseChosenOne() {
$.get("generate.php", function(data) {
var chosenOne = targetLocation[data.randomNumber];
}, "json");
alert(chosenOne);
}
How can I fix this? How can I use the variable "chosenOne" outside of that function in the GET request?
You have to use the jQuery plugin getURLParam
value = $.getURLParam("paramName");
'chosenOne' only exists inside your callback function, and your code will hit the alert() before the callback has even run...
function chooseChosenOne() {
$.get("generate.php", function(data) {
doSomethingWithChosenOne(targetLocation[data.randomNumber]);
}, "json");
}
function doSomethingWithChosenOne(v){
alert(v);
}
At the time you call alert(chosenOne);, the Ajax callback is not executed yet. Ajax is asynchronous. The function chooseChosenOne will not wait until the Ajax called finished, it will return immediately.
You can only work the return value in the callback:
function chooseChosenOne() {
$.get("generate.php", function(data) {
var chosenOne = targetLocation[data.randomNumber];
alert(chosenOne);
}, "json");
}
So what you have to do is to make your function accept a callback which gets called as soon as the value is available:
function chooseChosenOne(callback) {
$.get("generate.php", function(data) {
callback(targetLocation[data.randomNumber]);
}, "json");
}
chooseChosenOne(function(theOne) {
// now do stuff with theOne here
});
See also:
jQuery: Return data after ajax call success
What I have to say about how to return data from an Ajax call.
I'm not massively experienced with JavaScript and I'm having trouble with variable scope and jquery. I have the following structure:
function pass_variables()
{
username = "efcjoe"
response = post_variables(username)
alert(response)
}
function post_variables(username)
{
$.post(
'/path/to/url/',
{
'username': username,
},
function(data)
{
valid = (data != 0) ? true : false
// OPTION 1: If I put return here...
return valid; // ... the alert box in pass_variables says "undefined"
},
"text"
);
// OPTION 2: If I put return here...
return valid; // ... The alert box does not pop up, and Safari debug gives
// me the error: "Can't find variable: valid"
}
Am I missing something there? I think valid should be a global variable, and therefore option 2 should work fine. I'm really not sure about option 1.
Can anyone give me any advice on the best way to get this working?
Thanks a lot.
Ajax calls are asynchronous which means they get called but do wait around for execution to complete. Basically your alert is firing before the ajax request has completed and run the callback function to change your variable.
The best thing you can do is actually pass a function to run when the ajax request has completed. This also negates the need for global variables which are frowned upon since other plugins, script can alter their state and leave your script open to errors, flaws etc
E.g
function foobar(){
//call function to do post request and also pass a function to run
//when post has returned
runPostRequest( callbackFn );
}
function runPostRequest(callback){
$.post( '/foo', callback );
}
function callbackFn( data ){
console.log('post request complete');
}
In your option 1 you are returning from the callback function, and its return value is never used because this function is only called when the Ajax request ends.
In the option 2, you are returning from your main function, but that return happens before the callback function assign any value to your valid variable.
I would refactor your code in this way, without using global variables:
function post_variables(username){
$.post('/path/to/url/',{
'username': username,
},
function(data){
var valid = data != 0;
// OPTION 3: Work in the callback function
alert(username);
alert(valid);
// OPTION 4: Pass the values and work on another function
otherFunction(username, valid);
},"text");
}
function otherFunction(username, isValid){
//...
}
Yeah, your problem is that you're not grasping some order of operations issues here. The function you're passing to $.post is a callback; it runs later, considerably after post_variables() finishes. post_variables() itself does not wait for the $.post to finish, so valid doesn't exist when you're trying to use it.
Remember that AJAX is asynchronous. The return valid; gets executed immediately after the $.post() is set up, but before the post has completed (and therefore, before valid is defined). What you probably want to do is this:
function post_variables(username)
{
var username = "efcjoe";
$.post(
'/path/to/url/',
{
'username': username,
},
function(data)
{
var valid = (data != 0) ? true : false
alert(valid);
},
"text"
);
}
And note that this no longer needs global variables, but function-scope variables that are declared using var.
You could solve the problem quite easily by assigning it a function instead of an inline one, and the event function does the alert:
function pass_variables()
{
username = "efcjoe"
response = post_variables(username);
}
function post_variables(username)
{
$.post(
'/path/to/url/',
{
'username': username,
},
receivedData,
"text"
);
}
function receivedData(data)
{
valid = (data != 0) ? true : false;
alert(valid)
}