I realize this is asked a lot and usually the answer is that AJAX is asynchronous and this is why it's returning undefined, but even though I set my async to false here, it's still returning undefined when the function is called. res is always undefined
function sendRequest(link, type, query) {
$(document).ready(function(){
$.ajax({
'url' : link,
'type' : type,
'data' : query,
'async' : false,
'dataType': "json",
'headers': {
'Cache-Control':'max-age=0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Content-Type':'application/x-www-form-urlencoded',
'Accept-Language':'en-US,en;q=0.8,ar;q=0.6',
},
'success': function(data) {
var res = data;
}
});
});
return res;
}
Also I am sure that the request is being sent correctly and that the response is received correctly as well
I think a better approach would be to have your sendRequest function return a jQuery Promise Object. As an example
function sendRequest(link, type, query) {
return $.ajax({
'url' : link,
'type' : type,
'data' : query,
'dataType': "json",
'headers': {
'Cache-Control':'max-age=0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Content-Type':'application/x-www-form-urlencoded',
'Accept-Language':'en-US,en;q=0.8,ar;q=0.6',
}
});
}
To use
sendRequest('/someurl', 'GET', {}).done(function(data) {
// do whatever you need with data here
});
You'll have to declare and assign res separately.
var res;
$.ajax({
// ...
'success': function (data) {
res = data;
}
});
return res;
Currently, res is being declared as a local variable solely inside the success callback. So, it won't be accessible to the rest of sendRequest().
Though, you should try to avoid using async: false with Ajax.
You can instead return the Deferred jqXHR provided by $.ajax(), allowing the calling function to add its own handler.
function sendRequest(link, type, query) {
return $.ajax({
// ...
});
}
sendRequest(...).done(function (data) {
// ...
});
More details and options are described in "How to return the response from an AJAX call?"
Firstly res should be outside ajax scope, and Secondly function will return before ajax call completes thats the reason its undefined:
$(document).ready(function(){
$.ajax({
'url' : link,
'type' : type,
'data' : query,
'async' : false,
'dataType': "json",
'headers': {
'Cache-Control':'max-age=0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Content-Type':'application/x-www-form-urlencoded',
'Accept-Language':'en-US,en;q=0.8,ar;q=0.6',
},
'success': function(data) {
MyFunction(data);
}
});
function MyFunction(data)
{
// do with ajax resonse what is needed
}
It's a scope problem.
You need to declare var res; in a scope that's accessible to the return, and just update that object inside of the AJAX.
function sendRequest(link, type, query) {
var res;
$(document).ready(function(){
$.ajax({
//...
'success': function(data) {
res = data;
}
});
});
return res;
}
AJAX is async (at least it should be, I would refrain from using async set to false), so the result will be undefined. Use a callback:
function sendRequest(link, type, query, callback) {
$.ajax({
..
..
'success': function(data) {
callback(data);
}
});
}
sendRequest(link, type, query, function(data) {
console.log(data); //YOUR DATA
});
Related
I'm trying to implement a function that after consulting a service brings the variables as global.
function ajax_test(str1, callback){
$.ajax({
url: '/path/service',
type: 'POST',
dataType: "json",
data: {'vars':$('form').serialize(), 'test':123},
success: function(data, status, xhr){
callback(data);
}
});
}
and I'm trying to call like this:
ajax_test("str", function(url) {
//do something with url
console.log(url);
});
Now, if I just call ajax_test() it returns an error, saying that callback is not a function.
How would be the best way to simply call the function and get the results to use global variables?
Edit:
I think a good question is: what is a good alternative to async: false? How is the best way to implement synchronous callback?
Edit 2:
For now, I'm using $.post() with $.ajaxSetup({async: false}); and it works how I expect. Still looking a way I could use with a callback.
Have to set the scope inside the success method. Adding the following should work.
function ajax_test(str1, callback){
$.ajax({
url: '/path/service',
type: 'POST',
dataType: "json",
data: {'vars':$('form').serialize(), 'test':123},
success: function(data, status, xhr){
this.callback(data);
}.bind(this)
});
}
As an argument of the ajax_test function, callback is in the scope of the ajax_test function definition and can be called anywhere there, particularly in the successcase. Note that calling ajax_test() without arguments will as expected make your code call a function that does not exist, named callback.
The following sends an Ajax request to the jsFiddle echo service (both examples of callback as anonymous or global function are given in the jsFiddle), and works properly :
function ajax_test(str1, callback){
$.ajax({
url: '/echo/json',
type: 'POST',
dataType: "json",
data: {
json: JSON.stringify({
'vars':$('form').serialize(),
'test':123
})
},
success: function(data, status, xhr){
callback(data);
}
});
}
ajax_test("unusedString", function(data){
console.log("Callback (echo from jsFiddle called), data :", data);
});
Can you check that the webservice you're calling returns successfully ? Here is the jsFiddle, I hope you can adapt it to your need :
https://jsfiddle.net/dyjjv3o0
UPDATE: similar code using an object
function ajax_test(str1) {
this.JSONFromAjax = null;
var self = this;
function callback(data) {
console.log("Hello, data :", data);
console.log("Hello, this :", this);
$("#callbackResultId").append("<p>Anonymous function : " + JSON.stringify(data) + "</p>");
this.JSONFromAjax = JSON.stringify(data);
}
$.ajax({
url: '/echo/json',
type: 'POST',
dataType: "json",
data: {
json: JSON.stringify({
'vars': $('form').serialize(),
'test': 123
})
},
success: function(data, status, xhr) {
console.log("Success ajax");
// 'self' is the object, force callback to use 'self' as 'this' internally.
// We cannot use 'this' directly here as it refers to the 'ajax' object provided by jQuery
callback.call(self, data);
}
});
}
var obj = new ajax_test("unusedString");
// Right after the creation, Ajax request did not complete
console.log("obj.JSONFromAjax", obj.JSONFromAjax);
setTimeout(function(){
// Ajax request completed, obj has been updated
console.log("obj.JSONFromAjax", obj.JSONFromAjax);
}, 2000)
You cannot expect the Ajax request to complete immediately (don't know how it behaves with async: false though, this is why you need to wait for a while before getting the actual response.
Updated jsFiddle here : http://jsfiddle.net/jjt39mg3
Hope this helps!
I'm sending ajax call and getting an answer that I need from the first ajax then I want to pass my result to my nested ajax, my var (result) is null in the nested ajax/settimeout fun, can I pass it ? Am I missing something ?
$.ajax({
url: '#Url.Action("getCustomerGuidId", "Document")',
type: 'POST',
cache: false,
data: { "classNum": currentclassNum},
contentType:'json' ,
dataType:'text',
success: function (result) {
alert(result);**-> is fine - not null**.
// a or result is null when I hit the getCurrentDoc- function althought I get the data I need from getCustomerGuidId function
var a = result;-> tried to pass it to a new var..IDK.. I
thought it will help... it didn't.
setTimeout(function () {
$.ajax({
type: "GET",
url: '#Url.Action("getCurrentDoc", "Document")',
contentType:'text',
data: a,-> here it's null
success: function (data) {
}
});
}, 2000);
},
error: function (result) {
alert("fail " + result);
}
});
You can try something like this will help to pass value to nested ajax call
function test(){
var myText = 'Hello all !!';
$.get({
//used the jsonplaceholder url for testing
'url':'https://jsonplaceholder.typicode.com/posts/1',
'method':'GET',
success: function (data) {
//updating value of myText
myText = 'welcome';
$.post({
'url':'https://jsonplaceholder.typicode.com/posts',
'method':'POST',
//data.title is the return value from get request to the post request
'data':{'title':data.title},
'success':function (data) {
alert(data.title +'\n' + myText);//your code here ...
}
});
}
});
}
An old question and you've likely moved on, but there's still no accepted answer.
Your setTimeout takes an anonymous function, so you are losing your binding; if you have to use a Timeout for some reason, you need to add .bind(this) to your setTimeout call (see below)
setTimeout(function () {
$.ajax({
type: "GET",
url: '#Url.Action("getCurrentDoc", "Document")',
contentType:'text',
data: a,
success: function (data) {
}
});
}.bind(this), 2000);
At a guess you're using a Timeout because you want to ensure that your promise (i.e. the first ajax call) is resolving prior to making the nested call.
If that's your intention, you can actually scrap setTimeout completely as you have the nested call in the first ajax success call, which only runs once the promise has been resolved (providing there isn't an error; if so, jQuery would call error rather than success)
Removing setTimeout means you won't lose your binding, and a should still be result (hopefully a is an object, otherwise your second call is also going to experience issues...)
Lastly, after overcoming the binding issue you wouldn't need var a = result; you should be able to pass result directly to your nested ajax call.
Good luck!
In the nested ajax you send a as a param name, not as a param value.
So you can try the following (change param to actual param name which your server expects):
$.ajax({
url: '#Url.Action("getCustomerGuidId", "Document")',
type: 'POST',
cache: false,
data: { "classNum": currentclassNum},
dataType:'text',
success: function (result) {
setTimeout(function () {
$.ajax({
type: "GET",
url: '#Url.Action("getCurrentDoc", "Document")',
data: {param: result},
success: function (data) {
}
});
}, 2000);
},
error: function (result) {
alert("fail " + result);
}
});
I´m using $.when to determine, when an array of ajax promises are finished. I encountered, that the moment $.when fires the ajax calls are finished, but their callbacks / done functions aren´t. How can I wait for the callbacks to be finished?
the ajax calls look like this:
$.ajax({
method: 'POST',
url: url,
data: formData,
processData: false,
contentType: false
}).then(
function(data) {
data = JSON.parse(data);
var url = data.url;
obj.set('src', url);
});
and $.when s.th. like this:
$.when(promises).done(function(){
// the values of objs change in the .done function of the request above
// but when the following ajax got fired, the values haven´t changed yet
if(DEV) console.info('send Json: ', objs);
$.ajax({
method: "POST",
url: url,
data: objs
});
});
I would do this by using jQuery v1.8 or later and using then rather than fail and done and success/failure callbacks:
var promise1 = $.ajax({
/* ...params...*/
}).then(
function(data) {
// Handle success; if you modify what you get, `return` it
// and it will get propagated
return /*...`data` or updated `data` as appropriate...*/;
},
function(error) {
// Handle failure
}
);
var promise2 = /*...*/;
Then
$.when(promise1, promise2).then(
function(data) {
// Handle overall success; this will be called after the
// earlier `then` callbacks on each request
},
function(error) {
// Handle failure
}
);
Live example on jsFiddle (sadly, Stack Snippets don't provide any ajax features); full source below
Note that $.when expects discrete arguments, not an array. If you really have an array, then:
$.when.apply($, promises).then(
// ...
);
...or of course on a modern JavaScript engine:
Promise.all(promises).then(
// ...
);
Full source of the fiddle above, which uses jQuery v2.2.4:
log("Starting");
var promise1 = $.ajax({
url: "/echo/json/"
}).then(
function(data) {
// Handle success; if you modify what you get, `return` it
// and it will get propagated
log("Got promise1's response, returning 'p1'");
return 'p1';
},
function(error) {
// Handle failure
}
);
var promise2 = $.ajax({
url: "/echo/json/"
}).then(
function(data) {
// Handle success; if you modify what you get, `return` it
// and it will get propagated
log("Got promise2's response, returning 'p2'");
return 'p2';
},
function(error) {
// Handle failure
}
);
$.when(promise1, promise2).then(
function(result1, result2) {
// Handle overall success; this will be called after the
// earlier `then` callbacks on each request
log("Both are done", result1, result2);
},
function(error) {
// Handle failure
}
);
function log() {
// Old-fashioned to stay ES5 compatible
$("<pre>").text(Array.prototype.join.call(arguments, ", ")).appendTo(document.body);
}
Can you chain your promises? With something like this (not tested):
$.ajax({
method: 'POST',
url: url,
data: formData,
processData: false,
contentType: false
}).then(
function(data) {
data = JSON.parse(data);
var url = data.url;
obj.set('src', url);
// return your promises (if possible, I don't know where they come from)
return promises
}).then(
function() {
if(DEV)
console.info('send Json: ', objs);
$.ajax({
method: "POST",
url: url,
data: objs
});
});
use this
$.ajax({
method: 'POST',
url: url,
data: formData,
processData: false,
contentType: false,
success: function(data){/* to handle success response */},
error: function(error){/* to handle error response */},
complete: function(data){/* to handle the response success or error*/}
});
the data = JSON.parse(data); in your ajax function is not mutating the data object but create a new data object, you need to return it back so the caller can grab it
Try it like this,
function getData(){
return $.ajax({
method: 'POST',
url: url,
data: formData,
processData: false,
contentType: false
}).then(
function(data) {
data = JSON.parse(data);
var url = data.url;
obj.set('src', url);
return data;
});
}
var data = $.when(promises).done(getData);
I have a function in which I execute an ajax request and wait till I get a response and return a value but the value returned is undefined. What is wrong?
function GetVMData(url_s){
return $.ajax({
url: url_s,
crossDomain: true,
dataType: 'jsonp',
error: function(xhr, status, error) {
alert('failed')
}
}).pipe(function(data) { return data[4]; });
}
If I print the value of data[4] within the ajax callback it prints the right value, therefore i know the request is going through but when I try this:
var cord;
cord = GetVMData(url).done(function(cpu_USG) {
return cpu_USG;
});
alert(cord)
the value of cord is wrong.
var cord;
cord = GetVMData(url).done(function(cpu_USG) {
return cpu_USG;
});
alert(cord)
This code runs asynchronously. So you need to perform everything in the callback, like:
GetVMData(url).done(function(cpu_USG) {
alert(cpu_USG);
});
Here:
var cord;
cord = GetVMData(url).done(function(cpu_USG) {
return cpu_USG;
});
alert(cord);
cord contains object, not the value. And by the way, you don't know where ajax calling will be finished, so you should be familiar with idea of callbacks..
As an example:
function makeRequest(url, callback) {
$.ajax({
url: url,
crossDomain: true,
dataType: 'jsonp',
error: function(xhr, status, error) {
alert('failed')
},
success: callback
});
}
var do_something = function (data) {
alert(data[4]);
};
cord = makeRequest(url, do_something);
I use this helper function to receive JSON results for my requests:
function getData(url) {
$.get(url,
function(data) {
response = data;
return response;
}, 'application/json');
}
I give it some string as a part of url from my web application, like '/api/getusers', so it looks like getData('/api/getusers'). Now I need that string result containing JSON data that I receive from the url to be assigned to my variable, so it would look like this: var result = getData('/api/getusers'). Then I will process this JSON data. The problem is with the returning the response variable. It's undefined. Thanks!
try this
function getData(url) {
var data;
$.ajax({
async: false, //thats the trick
url: 'http://www.example.com',
dataType: 'json',
success: function(response){
data = response;
}
});
return data;
}
It's an asynchronous operation, meaning that function(data) { ... } runs later when the response from the server is available, long after you returned from getData(). Instead, kick off whatever you need from that function, for example:
function getData(url, callback) {
$.get(url, callback, 'application/json');
}
Then when you're calling it, pass in a function or reference to a function that uses the response, like this:
getData("myPage.php", function(data) {
alert("The data returned was: " + data);
});
Use $.ajax
$.ajax({
url: 'http://www.example.com',
dataType: 'json',
success: function(data){
alert(data.Id);
}
});