Is it possible to pass data through a Ajax request to the Callback function without global variables?
for e.g. this request function should pass the passData through the callback function which should get also normal response data?!
function rquest(callback, passData){
$.ajax({
type: "POST",
url: someURL,
success: callback(passData)
});
};
function myCallback(data, passData){
var responseData = data;
var SomeOtherData = passData
//do Something
};
rquest(myCallback, "Hello World");
so "Hello World" should be in passData and data should be the normal response from server...if i do it in this way data is "Hello World" and passData is undefined.
Wrap the call to the provided callback in an anonymous function. Try this:
function rquest(callback, passData){
$.ajax({
type: "POST",
url: someURL,
success: function(data) {
callback(data, passData)
}
});
};
function myCallback(data, passData) {
var responseData = data;
var SomeOtherData = passData
//do Something
};
rquest(myCallback, "Hello World");
I found the answer in the below link - some more patterns are available to achieve this -
Adding some of the content from the reference answer.
The pattern you'd like to use could work if you create a closure inside your rssToTarget function:
function rssToTarget(element) {
return function (xmlData) {
// work with element and the data returned from the server
}
}
function doSomething(url, elem) {
$.ajax({ type: "GET",
url: url,
dataType: "xml",
success: rssToTarget(elem)
});
}
When rssToTarget(elem) is executed, the element parameter is stored in the closure, and the callback function is returned, waiting to be executed.
Reference link https://stackoverflow.com/a/1194187/3082706
Related
I have looking for the solution with my case. In other question variable from ajax success will execute like this:
$.ajax({
...,
success: function(data) {
myFunction(data);
});
myFunction(data){
// process the data here ..
}
But in my case I call another ajax(2) with ajax(1). And really need that variable from ajax(2) to ajax(1) for process. My code look like this:
$("#formVerify").submit(function(event) {
$.ajax({
....
success: function(data){
var result= call_id(data.id);
console.log(result);
}
});
});
function call_id(data) {
var output = null;
$.ajax({
....
success: function(result){
output = result;
}
});
return output;
}
the result will always null because I set output to, or sometimes it is undefined if I don't set the value to null. I tried async: false but in my machine it wouldn't work. Need help thank you
Remember Ajax call doesn't return result, you can't use return statement in ajax call. You can get the result only using callback/promises.
Change you first ajax call to pass the callback instead of trying to get the return value:
$("#formVerify").submit(function(event) {
$.ajax({
....
success: function(data){
call_id(data.id, function(result){
console.log(result);
});
}
});
});
and change your second ajax call_id function to take callback as parameter like this:
function call_id(data, callback) {
$.ajax({
....
success: callback
});
}
Apologies if this is a duplicate question, I've followed some steps from another question which didn't seem to help me. I am trying to retrieve some JSON data, store part of the data into a variable and use that variable in a separate function outside of the AJAX request.
My expected response from the json data is http://localhost:8000/tutorials/retrieve/?page=2 (This response shows if I log the variable inside of the AJAX code) however the actual response I get when I try to log the variable from another function is as follows:
n.Event {originalEvent: MouseEvent, type: "click", timeStamp: 1436727171161, jQuery21304066238570958376: true, toElement: div#loadmore.recentTutorials…}
Here is the current code
var recentFirstPage = '';
function retrieveTutorials(){
$.ajax({
type: "GET",
url: "/tutorials/retrieve",
dataType: "json",
success: function(data){
**some unrelated parsing code here**
//Set the variable to what I need
recentFirstPage = data.next_page_url;
},
error: function() {
alert("An error occurred processing AJAX request.");
}
});
}
$('#main-content-wrap').on('click', '.recentTutorials', function(recentFirstPage){
//Does not return expected result
console.log(recentFirstPage);
});
When I click .recentTutorials I expect the console to log the data from JSON however it doesn't. Can someone help clear up my error(s)?
The reason that it doesn't log the data from JSON s that the call is asynchronous. This means that the function will execute top to bottom without waiting for the call to finish.
One method that's used is to leverage deferred objects which return a promise on completion. You can accept an anonymous function to the invoker function so that it's call back is executed within the scope of the click.
Observe:
function retrieveTutorials(){
return $.ajax({
type: "GET",
url: "/tutorials/retrieve",
dataType: "json"
});
}
$('#main-content-wrap').on('click', '.recentTutorials', function(){
//store our function call as an ajax promise
var promise = retrieveTutorials();
//wait for the ajax to return so we can mutate the data
promise.done(function(data){
//now our data will be properly
recentFirstPage = data.next_page_url;
});
});
It seems to me that you are trying to log the data before the ajax is completed. It`s better to use deferreds . Try this:
function retrieveTutorials(){
return $.ajax({ // will return deferred object
type: "GET",
url: "/tutorials/retrieve",
dataType: "json",
success: function(data){
**some unrelated parsing code here**
//Set the variable to what I need
recentFirstPage = data.next_page_url;
},
error: function() {
alert("An error occurred processing AJAX request.");
}
});
}
$.when( retrieveTutorials() ).done(function ( data ) {
console.log(recentFirstPage);
});
The parameter in your click handler is the last and final nail in your coffin. It's always the jquery event and you shouldn't handle it at all.
You do need to call the retrieveTutorials() function within the handler and you need to pass it a callback function that will be executed on success. So your retrieveTutorials() function will look something like this:
function retrieveTutorials(success){
$.ajax({ type: "GET", url: "/tutorials/retrieve",
dataType: "json",
success: success,
error: function() { alert("An error occurred processing AJAX request.");
} }); }
And your click handler:
$('#main-content-wrap').on('click', '.recentTutorials', function(){
retrieveTutorials(function(data){
console.log(data.next_page_url);
});
});
You can also use all the promise based goodness in the other anwers, but the above would be an idiom you'll see again and again.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I'm trying to set the results of an ajax request so that it is available globally throughout my code. I originally tried just wrapping the request in a function, returning the data and then setting a global variable to that function call, but it just returned as undefined. I have no idea how to proceed.
var myId = getMyId();
getMyId();
function getMyId(){
$.ajax({
url: '/who_am_i',
method: 'GET',
dataType: 'json',
success: function(data) {
return data;
}
});
}
console.log(myId);
If you need code to understand my question, The code above does not work. I'm trying to find one that does
var myId;
function getMyId(){
$.ajax({
url: '/who_am_i',
method: 'GET',
dataType: 'json',
success: function(data) {
// you dont return vars from a async callback, from here you can access the global scope like this
myId = data;
}
});
}
getMyId(); // execute it
You can use the myId var, only after the callback has finished. So perhaps it would be better to call a function so you have more control of the execution flow.
var myId;
function getMyId(){
$.ajax({
url: '/who_am_i',
method: 'GET',
dataType: 'json',
success: function(data) {
init(data);
}
});
}
function init(data){
myId = data;
// do your stuff here to guarantee that myId is populated
}
getMyId(); // execute it
Sorry to be so verbose, but even better:
var myId;
function getMyId(callback){
$.ajax({
url: '/who_am_i',
method: 'GET',
dataType: 'json',
success: callback
});
}
function init(data){
myId = data;
// do your stuff here to guarantee that myId is populated
}
getMyId(init); // execute it
Several ways to achieve the same result should help others understand how data flows in async calls.
I've been trying to figure this one out since my earlier question.
I can receive the data, as I see it under resources using Develop > Show Web Inspector on safari. But I can't seem to assign it successfully to a variable to use later on.
<script>
function getData () {
$.ajax
({
type: "GET",
url: "https://myjirasite.com/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
//async: true,
beforeSend: function (xhr) {xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));},
success: function (){
//Attempt 1 at outputting the result to an alert.
alert(JSON.parse(data));
}
});
}
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return 'Basic ' + hash;
}
</script>
In a second attempt I assign the ajax call to a variable and attempt to print that out to an alert. No success. the alert is empty
var jqXHR = $.ajax
({
type: "GET",
url: "https://myjirasite/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
async: false,
beforeSend: function (xhr) {xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));},
success: function (data){
alert(JSON.parse(data));
}
});
alert(JSON.parse(jqXHR.responseText));
I know that the issue lies with ajax calls being asynchronous, but I can't figure out how to write the callback such that I can get the json data into a variable to use later in via a different function.
Don't set async: false, as this will block the browser whilst your Ajax request is processed.
Instead, you can use promises, or call a further function from within your success callback.
Something like:
function getData(){
return $.ajax({
type: "GET",
url: "https://myjirasite/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
beforeSend: function(xhr){
xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));
}
});
}
getData()
.done(function (data){
console.log(JSON.parse(data));
})
.fail(function(){
console.log("Error!");
});
<script>
var getData = function() {
$.ajax
({
type: "GET",
url: "https://myjirasite.com/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
//async: true,
beforeSend: function (xhr) {xhr.setRequestHeader('Authorization', make_base_auth("myusername", "mypassword"));},
success: function (){
//Attempt 1 at outputting the result to an alert.
alert(JSON.parse(data));
getData.data= JSON.parse(data);
}
});
}
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return 'Basic ' + hash;
}
setTimeout(function(){console.log(getData.data);}, 3000); // Fire after 3 seconds to get data.
</script>
I don't think $.ajax actually returns anything - but I could be wrong. Either way, that's not too important, because you shouldn't rely on the results of an ajax call being available immediately. Your alert statement is firing before the Ajax request is finished - it sounds like you know that already.
When leveraging asynchronous calls (ajax), its a best practice to have any logic that relies on the data returned from the call to be done in (or triggered by) a callback (or as #Jack Zelig mentions, promises). This is what success parameter of $.ajax is all about. It will get called once the request completes successfully. You can also define complete and error callbacks - which fire once the request is complete (regardless of status) and once the request fails respectively.
So to summarize, your best option is probably this:
var jqXHR = $.ajax
({
type: "GET",
url: "https://myjirasite/jira/rest/api/2/project/ON/versions?",
dataType: 'jsonp',
success: successHandler
});
function successHandler(data) {
alert(JSON.parse(data));
}
In this way, only once data is received will an alert be shown that will contain the data.
I have a slow function that does an AJAX request:
function X(param1,param2){
var params={
type: "POST",
url: "./ajax/useful.php",
data: "param1="+param1+"¶m2="+param2,
success: function(msg){
//do something
}
};
var result=$.ajax(params).responseText;
}
Everything works fine when I call X("asdf","qwerty").
Now, what I want to do is to be able to call function X as follows:
function X(param1,param2,function(){alert('hi');}){
var params={
type: "POST",
url: "./ajax/useful.php",
data: "param1="+param1+"¶m2="+param2,
success: function(msg){
/////
//I want to be able call the function in the 3rd parameter (alert in this case)
/////
}
};
var result=$.ajax(params).responseText;
}
Now you might say why don't I just call alert('hi') directly inside the success. Sure I can do this, but I want to be able to vary what goes on inside the called function (not just a simple alert('hi'), depending on who's calling X.
You declare your X function like this:
function X(param1,param2,callback){
...use the callback like this:
success: function(msg){
callback();
}
...and call X like this:
X('a', 'b', function(){alert('hi');});
This works because your success handler is a closure over the data within your X function, including its arguments. It has a live reference to that information (even after X returns), and so later when the Ajax call completes, it can still use the callback argument. More on closures here: Closures are not complicated
function X(param1,param2,f){
var params={
type: "POST",
url: "./ajax/useful.php",
data: "param1="+param1+"¶m2="+param2,
success: function(msg){
f();
}
};
var result=$.ajax(params).responseText;
}
should work.
You can no call X like this:
X(param1,param2,function(){dowhatever})