I'm currently working on a project with javascript and jquery.
I'm using a $.ajax call to ask the server for some data. This call is being made within an object I created.
On success, I want to update the data members of such object with the data recieved. It looks something like so:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
success: function ( data ) {
// update data
}
});
};
};
For passing the original object (Caller) to the succes function, I've tried the following:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
var _this = this;
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
success: function ( data ) {
// update data
_this.data1 = data.data1;
_this.data2 = data.data2;
}
});
};
};
Then I tried:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
_this: this,
success: function ( data ) {
// update data
var _this = this._this
_this.data1 = data.data1;
_this.data2 = data.data2;
}
});
};
};
And then:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
context: this,
success: function ( data ) {
// update data
this.data1 = data.data1;
this.data2 = data.data2;
}
});
};
};
In all the cases above, it seems that a copy of the object, rather than the original one, is being pass to the function, so the original values are not
changed.
Is there a way to change the originals values of the object or pass the original one? I hope you can help me, i've stuck with this for a while.
If you send a request to another site, you must do
crossDomain: true
or
If you want to do data return, you must do
async: true
Example:
var data_1 = 0;
ajax success function data_1 = data.data_1
return data_1;
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I've built a function to handle a request that I intend to use in various pages. But I can't find a way to access it's return! Here is what my code looks like:
function buscaIdEmpresa() {
var jsonEmail = { "email": emailCurrentUser };
var jsonEmailString = JSON.stringify(jsonEmail);
var test = $.ajax({
url: "https://localhost:44326/test",
type: "post",
async: false,
crossDomain: true,
data: jsonEmailString,
contentType: "application/json",
dataType: "json",
complete: function (data) {
var id = data.responseText;
alert(id)
//this returns id as expected
return id;
}
});
alert(test)
//this returns object Object
return test;
}
function carregaConfigList() {
var id = buscaIdEmpresa()
alert(id)
//this returns object Object
}
Also I am not entirely sure that this is the correct way to tackle the problem. I'm open to suggestions, but I would not like to write the entire ajax function every single time the request needs to be done. How can I access the object value? Is there a more 'correct' way of doing this?
Couple ways you could do this, my preferred method is using async/ await
function buscaIdEmpresa() {
return new Promise(resolve => {
var jsonEmail = { "email": emailCurrentUser };
var jsonEmailString = JSON.stringify(jsonEmail);
$.ajax({
url: "https://localhost:44326/test",
type: "post",
async: false,
crossDomain: true,
data: jsonEmailString,
contentType: "application/json",
dataType: "json",
complete: function (data) {
var id = data.responseText;
resolve(id);
}
});
})
}
async function carregaConfigList() {
var id = await buscaIdEmpresa()
alert(id)
}
But you could also use a callback pattern
function buscaIdEmpresa(callback) {
var jsonEmail = { "email": emailCurrentUser };
var jsonEmailString = JSON.stringify(jsonEmail);
$.ajax({
url: "https://localhost:44326/test",
type: "post",
async: false,
crossDomain: true,
data: jsonEmailString,
contentType: "application/json",
dataType: "json",
complete: function (data) {
var id = data.responseText;
callback(id);
}
});
}
function carregaConfigList() {
buscaIdEmpresa(function(id){
alert(id)
})
}
The alert at the start shows "undefined", why?
The alerts come in this order:
"success!"
"Data" (what it should be)
"undefined"
I read through multiple threads, the problem was always that ajax was asynchronous, so the data was not defined when it was accessed, but in my case the data is there, the alert in my function shows the data BEFORE the other alert where it is undefined!
Very grateful for any help!
I got this code
var data = getData("");
alert(data); <<<<<<< UNDEFINED
function getData(fileName) {
$.ajax({
async:false,
type: "GET",
url: "breastCancer.csv",
dataType: "text",
success: function (data) {
var arrData = processData(data);
alert("success!");
alert(arrData); <<<<< WORKS GREAT
return arrData;
},
});
}
function processData(data) {
var arrData = CSVToArray(data);
dimensions = arrData[0];
var objects = [];
objects[0] = dimensions;
for (var i = 1; i < arrData.length; i++){
objects[i] = new Object();
for (var j = 0; j < dimensions.length; j++){
objects[i][dimensions[j]] = arrData[i][j];
}
}
return objects;
}
To clarify, I know asynchronous is the way to go for user experience, but this page just has to show data from this call, so its okay for me to wait for it.
Your getData function doesn't return anything.
You need to return it from the function itself.
function getData(fileName) {
$.ajax({
async:false,
type: "GET",
url: "breastCancer.csv",
dataType: "text",
success: function (data) {
var arrData = processData(data);
alert("success!");
alert(arrData); <<<<< WORKS GREAT
return arrData;
},
});
}
^ This returns the data within getData. But getData doesn't do anything with it: such as returning it.
function getData(fileName) {
var ourData = "";
$.ajax({
async:false,
type: "GET",
url: "breastCancer.csv",
dataType: "text",
success: function (data) {
var arrData = processData(data);
ourData = arrData;
},
});
return ourData;
}
This returns the data from getData to whatever calls that function.
edit: also, don't use async:false. Your browser won't capture any events happening until that AJAX completes. The benefit of asynchronous JS is that...we can! And in this case should.
Preface: Don't use async: false. But answering the question:
getData doesn't return anything. You're doing a return from the success callback, but that returns something from the success callback, not getData.
To change it so getData returns something, you'd do this:
function getData(fileName) {
var arrData;
$.ajax({
async:false,
type: "GET",
url: "breastCancer.csv",
dataType: "text",
success: function (data) {
arrData = processData(data);
},
});
return arrData; // <=== Now `getData` returns something
}
But don't do that. Instead, embrace asynchronous programming and remove async: false. For instance, a callback:
function getData(fileName) {
$.ajax({
async:false,
type: "GET",
url: "breastCancer.csv",
dataType: "text",
success: function (data) {
callback(processData(data));
},
});
}
...called like this:
getData(function(data) {
alert(data);
});
...or a promise ($.ajax returns one, of sorts):
function getData(fileName) {
return $.ajax({
async:false,
type: "GET",
url: "breastCancer.csv",
dataType: "text",
success: function (data) {
callback(processData(data));
},
}).then(data) {
return processData(data); // <== Becomes the resolution value of `getData`'s promise
});
}
and then
getData().then(function(data) {
alert(data);
});
data is undefined because the function getData doesn't return anything. You should have a look at promises.
I am trying to pass param between two different ajax calls, the params only exist inside the ajax scope but not outside of it.
i saw the option of calling from the first ajax success section to another ajax and i don't want this, is their any other way?
my code
jQuery.ajax({
url: '/modules/products/ajax.php',
data: {
prod_id: prod_id,
act: 'get_selected_values_for_sub_cat'
},
type: 'POST',
async: false,
dataType: 'json',
success: function(data) {
var res = JSON.stringify(data);
res = jQuery.parseJSON(res);
var selected_array = [];
jQuery.each(res, function(key1, value1) {
selected_array[key1] = jQuery.parseJSON(value1);
})
}
});
console.info("selected_array", selected_array);
i try this
function ajax_get_selected_values_for_sub_cat() {
return jQuery.ajax({
url: '/modules/products/ajax.php',
data: {
prod_id: 123,
act: 'get_selected_values_for_sub_cat'
},
type: 'POST',
async: false,
dataType: 'json',
success: function(data) {
}
});
}
var re = ajax_get_selected_values_for_sub_cat();
res = JSON.stringify(re);
res = jQuery.parseJSON(res);
var selected_array = [];
jQuery.each(res, function(key1, value1) {
selected_array[key1] = jQuery.parseJSON(value1);
})
console.info("selected_array", selected_array);
what am i missing ?
thanks
ajax function returns an object that implements the promise interface. You can implement it like this:
function ajax_get_selected_values_for_sub_cat(id) {
return jQuery.ajax({
url: '/modules/products/ajax.php',
data: {
prod_id: id,
act: 'get_selected_values_for_sub_cat'
},
type: 'POST',
async: false,
dataType: 'json'
});
}
var promise = ajax_get_selected_values_for_sub_cat(123);
promise.done(function(re){
res = JSON.stringify(re);
res = jQuery.parseJSON(res);
var selected_array = [];
jQuery.each(res, function(key1, value1) {
selected_array[key1] = jQuery.parseJSON(value1);
})
console.info("selected_array", selected_array);
});
http://api.jquery.com/jQuery.ajax/#jqXHR
You can use callback methods as below-
function ajax_get_selected_values_for_sub_cat(successCallback)
{
jQuery.ajax({
url : '/modules/products/ajax.php',
data : {prod_id:123,act:'get_selected_values_for_sub_cat'},
type : 'POST',
async: false,
dataType: 'json',
success:function(data){
successCallback(data);
}
});
}
ajax_get_selected_values_for_sub_cat(function(re){
res =JSON.stringify(re);
res = jQuery.parseJSON(res);
var selected_array =[];
jQuery.each( res, function( key1, value1 ) {
selected_array[key1]=jQuery.parseJSON(value1);
})
console.info("selected_array",selected_array);
});
I am loading 2 XML documents that both run functions on success, although the function for the 2nd XML document is dependant on the 1st being complete.
If I have async:true:
1st XML
function XmlDataTypes() {
var result = null;
var scriptUrl = "http://domain.com/xml/test.XmlDataTypes?AccountId=" + AccountId;
$.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
//create array to be used in second XML
for (var i = 0; i < xmlRows.length; i++) {
var dataType = xmlRows[i];
var dataTypeId = nodeValue(dataType.getElementsByTagName("DataTypeId")[0]);
var dataTypeName = nodeValue(dataType.getElementsByTagName("DataTypeName")[0]);
dataTypeArray.push({ dataTypeId: dataTypeId, dataTypeName: dataTypeName, position: i, markerArray: [] });
}
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
return result;
}
2nd XML
function XmlAmenityData() {
var result = null;
var scriptUrl = "http://domain.com/xml/test.XmlAmenityData?AccountId=" + AccountId;
$.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
//store this info in markerArray in dataTypeArray
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
return result;
}
The XML data can loaded in a random order so the function for the second document will error if the 1st hasn't completed.
If I set:
async: false
It works correctly but I get a warning:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
Is there a way around this without using:
async: false
Since the 2nd xml is dependent on the 1st, you can define a callback on success.
Also since ajax is async, you must assign the result when the callback is called. You can define a variable ourside of your function (in this case an array) and put the data there.
var result = [];
function XmlDataTypes(url, accountId, callback) {
var scriptUrl = url + accountId;
$.ajax({
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
// do something
result.push(data);
if(typeof callback == 'function') {
callback();
}
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
}
function doSomething() {
// Do something to store this info in markerArray in dataTypeArray
// XmlAmenityData is in results var.
}
And you can use it like so
var _callback = XmlDataTypes("http://domain.com/xml/test.XmlAmenityData?AccountId=", "1234", doSomething);
XmlDataTypes("http://domain.com/xml/test.XmlDataTypes?AccountId=", "1234", _callback);
EDIT: Updated script based on given scenario.
You could try to return the $.ajax as a promise:
function XmlDataTypes() {
// note domain.com was changes to example.com - this should be changed back
var scriptUrl = "http://example.com/xml/test.XmlDataTypes?AccountId=" + AccountId;
return $.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
//create array to be used in second XML
for (var i = 0; i < xmlRows.length; i++) {
var dataType = xmlRows[i];
var dataTypeId = nodeValue(dataType.getElementsByTagName("DataTypeId")[0]);
var dataTypeName = nodeValue(dataType.getElementsByTagName("DataTypeName")[0]);
dataTypeArray.push({ dataTypeId: dataTypeId, dataTypeName: dataTypeName, position: i, markerArray: [] });
}
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
}
Then calling them in sequence :
XmlDataTypes.done(XmlAmenityData);
Here is some more documentation :
http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html
I found this question which is almost exactly the same: Return value from nested function in Javascript
The problem is that the function is passed to jQuery's $.ajax function. Here's what i have:
function doSomething() {
// Do some stuff here
console.log(getCartInfo());
}
function getCartInfo() {
var url = blog_location + '?reqCartData=1';
$.ajax({
url: url,
type: 'get',
success: function(data) {
return data; <------------- This
}
});
}
I need to return data to the doSomething function, if that makes sense. I tried to return the entire $.ajax function but that returned the whole object. Any ideas?
Send a callback function:
function getCartInfo(onSuccess) {
var url = blog_location + '?reqCartData=1';
$.ajax({
url: url,
type: 'get',
success: function(data) {
onSuccess(data);
}
});
}
getCartInfo(function(data) {
console.log(data);
});
try this
function doSomething(date) {
........your data
}
function getCartInfo() {
var url = blog_location + '?reqCartData=1';
$.ajax({
url: url,
type: 'get',
success: function(data) {
doSomething(data);
}
});
}