Jquery ajax promise returning undefined - javascript

My second ajax call always returning undefined.
var getrpmData = fetchAjaxData(
{
"MachineID": MachineID,
"diaVal": diaVal,
"ggVal": ggVal,
"ITEMID": ITEMID
},
"url_to_call");
getrpmData.then((rpmData) => {
console.log(rpmData.d);//getting desired value from this
if (rpmData.d) {
shifHourUsigRPM(rpmData.d);
}
})
.then((prodRate) => {
console.log(prodRate.d.KnittingQty);//not getting value
})
.fail((err) => {
console.log(err);
}
);
// Generic function to make an AJAX call
var fetchAjaxData = function (dataParam, dataURL) {
// Return the $.ajax promise
return $.ajax({
beforeSend: function () { $.blockUI(); },
complete: function () { $.unblockUI(); },
type: "POST",
url: dataURL,
dataType: "JSON",
contentType: "application/json;charset=utf-8",
data: JSON.stringify(dataParam)
});
}
function shifHourUsigRPM(rpm) {
var KnittingWorkOrderId = GetValue($("#cmbKWO").val(), 'dlKWO');
var ITEMID = $("#cmbFabName").val();
var machineId = GetValue($("#cmbMachineID").val(), 'dlMachineID');
//fetchAjaxData(
// { "this_RPM": rpm, "fab": ITEMID, "machineId": machineId, "KWOID": KnittingWorkOrderId },
// "pageKnittingProductionPlanning_MachineWise.aspx/KPP_Load_QtyByRPM");
return $.ajax({
type: "POST",
beforeSend: function () { $.blockUI(); },
complete: function () { $.unblockUI(); },
url: "pageKnittingProductionPlanning_MachineWise.aspx/KPP_Load_QtyByRPM",
dataType: "JSON",
contentType: "application/json;charset=utf-8",
data: JSON.stringify({ "this_RPM": rpm, "fab": ITEMID, "machineId": machineId, "KWOID": KnittingWorkOrderId }),
success: function (data) {
//var result = data.d;
}
});
my back end web service is working fine, and returning desired value but not getting that value on second console.log call
getting below response from network response:
{"d":{"__type":"BLL.Kniting_BLL.KnittingQty","TotalFabNeed":"5 is production rate","RemFabQty":null}}
I'm expecting my second console.log should print
"5 is production rate"
, but getting undefined printed on console

Your first then callback is not returning a value, so the second then callback
will get undefined as argument.
You should return the value that shifHourUsigRPM(rpmData.d) returns (i.e. a promise), so add return before that call.
getrpmData.then((rpmData) => {
if (rpmData.d) {
return shifHourUsigRPM(rpmData.d);
// ^^^^^^
}
})

Related

how to catch the jquery ajax function return value in another variable

I am looking to store a value which is return by the AJAX function, here is the my code, in the AJAX success it is showing well, but when am storing that data which is saying undefined.
The following serviceNumber, which I am storing the enCrypt return value
var serviceNumber = enCrypt(typeofServiceNumber);// when am catching the function data which is saying "undefined"
the following code is my ajax function
function enCrypt(id) {
if (id > 0) {
$.ajax({
url: $("baseUrl").html() + "JobProfiles/Encryption",
type: "POST",
dataType: "json",
data: { Id: id },
success: function (encdata) {
return encdata;
},
error: function (data) {
$('#loading').hide();
}
});
}
}
Can you help me to know what is wrong in my code? Thanks in advance.
You can't use return like this, because the function is async + it's a function in a function...so actually yeah you cant return there xD
Just do something like:
enCrypt(typeofServiceNumber);
//and in your ajax:
success: function (encdata) {
go_on(encdata);
},
//and then
function go_on(serviceNumber)
{
//here you can use it :D
}
just add the
cache: false,
async: false,
to you ajax function
function enCrypt(id) {
var encnum;
$.ajax({
url: $("baseUrl").html() + "JobProfiles/EncodeIds",
type: "POST",
cache: false,
async: false,
dataType: "Json",
data: { Ids: id },
success: function (encdata) {
encnum = encdata;
},
error: function (data) {
$('#loading').hide();
}
});
return encnum;
}

Javascript - why is this undefined?

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.

Returning String Result from Ajax Method

I have a DoughnutChart chart and I would like to change the color of its parts regarding color hexa-codes saved in the database I used this Ajax method to get the color string by invoking an action method that returns JSON Result ,
getcolors: function getcolors(name) {
return $.ajax({
url: "/api/ideas/getcolors",
data: { name: name },
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data, textStatus, jqXHR) {
// return data;
},
error: function (data) {
// return "Failed";
},
async: true
});
but instead of receiving the string I received Object {readyState: 1} in the console window
However, I can find the color value stored in ResponseText element.I need your help in how can I get the color value as string.
EDIT :
To make things more clear that's where I would like to invoke the ajax method to receive the color string then I will be able to push in the chart color array .
getColorArray: function getColorArray(categories) {
var colors = [];
for (var i = 0; i < categories.length; i++) {
console.log(this.getcolors("Risk"));
//colors.push(this.getcolors(categories[i]));
}
return colors;
}
Why your code is like this?
success: function (data, textStatus, jqXHR) {
// return data;
},
Did you use it?
success: function (data, textStatus, jqXHR) {
console.log(data);
}
Ok, i got it. When you use an ajax request your will work with asynchronous data, to do this you need return a promise in your method. Please, try to use the code below.
getcolors: function getcolors(name) {
return $.ajax({
url: "/api/ideas/getcolors",
data: { name: name },
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
});
}
And for use your function use this code:
getcolors("name").done(function(result){
console.log(result);
});
Or you can use a callback
getcolors: function getcolors(name, success, error) {
return $.ajax({
url: "/api/ideas/getcolors",
data: { name: name },
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
success(data);
},
error: function(data){
error(data);
}
});
}
... And for use with callbacks:
getcolors("name", function(data){
//success function
console.log(data);
}, function(){
//Error function
console.log(data);
})
Try one of this options and tell the result.
The Solution
First of all I would like to thank Mateus Koppe for his efforts, through his solution I got the way to solve my problem ..
What I did simply is just I received the ResponseText from the incoming successful result in my Ajax method and then I passed it to a callback function that handles the result like the following :
getcolors: function getcolors(name, handleData) {
$.ajax({
url: "/api/ideas/getcolors",
data: { name: name },
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
handleData(data.responseText);
//return data.responseText;
},
error: function (data) {
handleData(data.responseText);
//return data.responseText;
},
async: false
});
then I worked with getColorArrayModified to loop through my categories list and populate its own color.
getColorArrayModified: function getColorArrayModified(categories) {
var colors = [];
for (var i = 0; i < categories.length; i++) {
this.getcolors(categories[i], function (output) {
colors.push(output);
});
}
return colors;
}
Thanks for all :).

ajax loading 2 XML documents in order without async:false

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

Looping through DOM elements

So this is my function, it deletes people from a list if you click on certain part of the form:
function ParticipantsDeleteClick(model, url) {
for (i in model.Participants) {
$("#delete" + i).click(function () {
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: model.Participants[i].Id }),
success: function (result) {
result ? $("#participant" + i).remove() : alert("Delete failed");
},
error: function () {
alert("Could not get a response from the server.");
}
});
});
}
}
For some reason, it doesn't matter which person you click on, it will always delete the last person from the list. And it only works once because once the last "i" gets deleted, every other click function points to that dom element with the last i's value.
I don't know why every time I'm adding a click function it all points to the last i's value in the loop. I modified the function adding a temp variable that took i's integer value and that didn't work either:
function ParticipantsDeleteClick(model, url) {
for (i in model.Participants) {
var temp = parseInt(i);
$("#delete" + temp).click(function () {
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: model.Participants[temp].Id }),
success: function (result) {
result ? $("#participant" + temp).remove() : alert("Delete failed");
},
error: function () {
alert("Could not get a response from the server.");
}
});
});
}
}
So I'm not sure how I can get this to work.
i is always overwritten in the loop. You need a closure, eg by using $.each(function(){..}, or by wrapping the loop's body in a self-invoking function.
function ParticipantsDeleteClick(model, url) {
$.each(model.Participants, function(i){ //The `function` creates a closure
$("#delete" + i).click(function () {
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: model.Participants[i].Id }),
success: function (result) {
result ? $("#participant" + i).remove() : alert("Delete failed");
},
error: function () {
alert("Could not get a response from the server.");
}
});
});
}
}
Basically, you need to introduce a closure to capture the value of i each time around the loop. Using $.each() will introduce a closure for you (something like this)
function ParticipantsDeleteClick(model, url) {
$.each(model.Participants, function(i,v) {
$("#delete" + i).click(function () {
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: model.Participants[i].Id }),
success: function (result) {
result ? $("#participant" + i).remove() : alert("Delete failed");
},
error: function () {
alert("Could not get a response from the server.");
}
});
});
});
}
You have 3 scope levels here:
loop scope
click handler scope
ajax success handler scope
So you will need for each of those scope preserve and pass the variables. The .bind() method allows you to pass arguments to the callback from the outer scope and the context parameter allows you to pass parameters to the AJAX success callback. So:
$.each(model.Participants, function(index, participant) {
var data = { index: index, participant: participant };
$('#delete' + index).bind('click', data, function(evt) {
// at this stage evt.data will point to what the data variable was pointing
// from the outer scope but at the moment this handler was bound
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: evt.data.participant }),
context: evt.data.index,
success: function (result) {
// since we have used the context parameter at this stage
// this will point to this parameter which is simply the index
result ? $('#participant' + this).remove() : alert('Delete failed');
},
error: function () {
alert('Could not get a response from the server.');
}
});
});
});
Or to break this into separate functions to make it more clear:
function handleClick(evt) {
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: evt.data.participant }),
context: evt.data.index,
success: ajaxSuccess,
error: ajaxError
});
}
function ajaxSuccess(result) {
result ? $('#participant' + this).remove() : alert('Delete failed');
}
function ajaxError() {
alert('Could not get a response from the server.');
}
and then finally:
function ParticipantsDeleteClick(model, url) {
$.each(model.Participants, function(index, participant) {
var data = { index: index, participant: participant };
$('#delete' + index).bind('click', data, handleClick);
});
}

Categories