Restructuring nested ajax calls so variables work - ajax

My "value" variables below are not being inherited into the second call. What is the recommended way to reconstruct this so that it works?
First, I get all the data from our data table. Then, I need to get pending changes from a completely different database (change control). I need to display the second data if it exists.
function getData(appid) {
$.ajax({
url: 'services/getData',
type: 'GET',
data: { 'appid': appid },
dataType: 'json',
success: function (data) {
var field1Value = data.field1;
var field2Value = data.field2;
var field3Value = data.field3;
//get pending changes
$.ajax({
url: 'services/getPendingChanges',
type: 'GET',
data: { 'appid': appid },
dataType: 'json',
success: function (data2) {
if (data2.field1 <> '') { field1value = data2.field1 };
if (data2.field2 <> '') { field1value = data2.field2 };
if (data2.field2 <> '') { field1value = data2.field2 };
},
complete: function () {
//set data in UI regardless of whether it came from getData or getPendingChanges
$('#txtField1').html(field1value);
$('#txtField2').html(field2value);
$('#txtField3').html(field3value);
}
})
}
})
}
of course when I do this, all the "*value" variables are undefined.

Unsure whether this will help you at all (and it probably won't), but this is what I've learned in my time in Javascript. But the nature of anon classes in javascript are so that you can use them without worry of variable collisions. The easiest way is that you funnel up to a higher scope variable to use later. But that's generally bad practice... So you could throw a wrapper around all that...

I ended up hiding the fields then calling the second ajax from the complete of the first. I set the fields in the success of the first call and also in the success of the second call, if they exist. Then I unhide them in the complete of the second.
function getData(appid) {
$('#txtField1').hide();
$('#txtField2').hide();
$('#txtField3').hide();
$.ajax({
url: 'services/getData',
type: 'GET',
data: { 'appid': appid },
dataType: 'json',
success: function (data) {
var field1Value = data.field1;
var field2Value = data.field2;
var field3Value = data.field3;
$('#txtField1').html(field1value);
$('#txtField2').html(field2value);
$('#txtField3').html(field3value);
},
complete: function () {
//get pending changes
$.ajax({
url: 'services/getPendingChanges',
type: 'GET',
data: { 'appid': appid },
dataType: 'json',
success: function (data2) {
if (data2.field1 <> '') {
field1value = data2.field1
$('#txtField1').html(field1value);
};
if (data2.field2 <> '') {
field2value = data2.field2
$('#txtField2').html(field2value);
};
if (data2.field3 <> '') {
field3value = data2.field3
$('#txtField3').html(field3value);
};
},
complete: function () {
$('#txtField1').show();
$('#txtField2').show();
$('#txtField3').show();
}
})
}
})
}
Ultimately instead of hiding them I would swap them out with a loading indicator. Also, I realize the BEST thing to do would be have a single web service that did all the logic in the background and just returned the appropriate data.

Related

Ajax GET call in a razor page not breaking inside the method in the controller

I have the following javascript using ajax:
function MoveToWeek(weekIndex) {
if (weekIndex == 1) {
var index = #Model.WeekIndex;
index = index+1;
$.ajax({
url: '#Url.Action("RenderCalendar", "Calendar")',
data: { weekIndex: index },
type: "GET",
success: function (data) {
$("#RenderCalendarArea").html(data);
}
});
}
else if (weekIndex == -1) {
var index = #Model.WeekIndex;
index = index+-1;
$.ajax({
url: '#Url.Action("RenderCalendar", "Calendar")',
data: { weekIndex: index},
type: 'GET',
success: function (data) {
$('#RenderCalendarArea').html(data);
}
});
}
}
And the following method in my controller "CalendarController":
[HttpGet]
public ActionResult RenderCalendar(int weekIndex = 0)
{
//..snip
}
I have confirmed the ajax code runs (if I put a javascript breakpoint on the $.ajax line, it'll break there). In addition the values in the ajax method do seem to be set correctly. In the debugger the javascript method has been compiled as such:
function MoveToWeek(weekIndex) {
if (weekIndex == 1) {
var index = 0;
index = index+1;
$.ajax({
url: '/Calendar/RenderCalendar',
data: { weekIndex: index },
type: "GET",
success: function (data) {
$("#RenderCalendarArea").html(data);
}
});
}
else if (weekIndex == -1) {
var index = 0;
index = index+-1;
$.ajax({
url: '/Calendar/RenderCalendar',
data: { weekIndex: index},
type: 'GET',
success: function (data) {
$('#RenderCalendarArea').html(data);
}
});
}
}
However, when this code runs, it does not break inside the method in the controller. Can anyone see why this doesn't work?
This particular partial view didn't use the layout file... which meant it didn't import the jquery lib. That's why it didn't work. Ooops.

What's the correct way to iterate through array and sending multiple ajax requests

I currently have some ajax that sends an array to php for processing. The array size at most would be around 1000 elements which will be enough for the server to time out while the php is processing. I would like to chunk the array and send it in batched ajax requests (or maybe just one at a time) that will each finish without timing out.
Below is my basic code structure. I'm trying to use promises and iterate through the chunks:
Here's the basic structure of the working function (non-promise version):
function ajax_function(big_array) {
$.ajax({
type: 'POST',
url: ajax.ajax_url,
data: {
'action': 'process_big_array',
'array_to_process': big_array
},
beforeSend: function () {
xxx
},
dataType: 'json',
success: process_big_array_chunk_handler,
error: function (xhr, desc, err) {
console.log(xhr);
console.log('Details: ' + desc + '\nError: ' + err);
}
});
}
Here's work in progress trying to add the loop and promise.
function ajax_function(big_array) {
var big_array_chunks = make it into chunks somehow;
$.each(big_array_chunks, function (big_array_chunk) {
var request = $.ajax({
type: 'POST',
url: ajax.ajax_url,
data: {
'action': 'process_big_array_chunk',
'array_to_process': big_array_chunk
},
dataType: 'json'
}).done(function (data) {
process_big_array_chunk_handler(data);
}).fail(function (xhr, desc, err) {
console.log(xhr);
console.log('Details: ' + desc + '\nError: ' + err);
});
});
}
Trying to get my head around how this all fits together:
each iteration of loop
responses from php
how to use my response handler when it's all done
fyi, this is being done within the context of WordPress if that matters.
Response to Bergi:
function ajax_function(big_array) {
var big_array_chunks = make big_array into chunks somehow;
var request = $.ajax({
type: 'POST',
url: ajax.ajax_url,
data: {
'action': 'process_big_array_chunk',
'array_to_process': big_array_chunk
},
dataType: 'json'
}).then(function (data) {
process_big_array_chunk_handler(data);
});
}
The simplest solution I can think of is to just pre-chunk the array and then just use the .reduce() design pattern for serializing promises.
function processBigArray(bigArray, chunkSize) {
// pre-split array into chunks
var chunkArray = [];
for (var i = 0; i < bigArray.length; i+=chunkSize) {
chunkArray.push(bigArray.slice(bigArray, i, chunkSize));
}
var results = [];
// use .reduce() design pattern for chaining and serializing
// a sequence of async operations
return chunkArray.reduce(function(p, chunk) {
return p.then(function() {
return $.ajax({
type: 'POST',
url: ajax.ajax_url,
data: {
'action': 'process_big_array',
'array_to_process': chunk
},
beforeSend: function () {
xxx
},
dataType: 'json',
}).then(function(data) {
results.push(data);
});
});
}, Promise.resolve()).then(function() {
// depending upon what your ajax returns, results might be an array of arrays
// that you would want to flatten
console.log(results);
return results;
});
}
// usage
processBigArray(someBigArray, 50).then(function(results) {
// process results here
}).catch(function(err) {
// deal with error here
console.log(err);
});

jqgrid onclickSubmitLocal using ajax

I am using the example here as a starting point. Everything works fine, I can submit the data back to the server and get a response. However I don't know how to connect the callback from the ajax to the jqgrid onclickSubmitLocal. I don't want to use alerts because even if there is an error the row is updated. I would like some how if there is an error the modal edit dialog to show the error and prevent it from updating the row. On success I would like the user to get a message saying data was saved.
Here is the relevant code:
function submitData(rowData){
var dataToSend = JSON.stringify(rowData);
$.ajax({
url: '/save',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: dataToSend,
dataType: 'json',
success: function (result) {
alert(' successfully saved.');
},
error: function(xhr, status, error) {
alert('Error processing submit ' + xhr.responseText);
}
});
}
I called the previous function from
onclickSubmitLocal = function (options, postdata) {
var $this = $(this), p = $(this).jqGrid("getGridParam"),// p = this.p,
idname = p.prmNames.id,
id = this.id,
idInPostdata = id + "_id",
rowid = postdata[idInPostdata],
addMode = rowid === "_empty",
oldValueOfSortColumn,
newId,
idOfTreeParentNode;
... same as in example from link above
if (postdata[p.sortname] !== oldValueOfSortColumn) {
// if the data are changed in the column by which are currently sorted
// we need resort the grid
setTimeout(function () {
$this.trigger("reloadGrid", [{current: true}]);
}, 100);
}
// !!! the most important step: skip ajax request to the server
options.processing = true;
submitData([postdata]);
},

Lambda fetching multiple records with contains query returns empty

I have this code:
public JsonResult EkranBilgiListele(List<int> ids)
{
dbReklam db = new dbReklam();
//int[] ids = { 14, 16 }; ids comes like this
db.Configuration.ProxyCreationEnabled = false;
var secilenEkranlar = db.tbl_Ekranlar.Where(ekranlar => ids.Contains(ekranlar.sektorID));
return Json(secilenEkranlar);
}
And an AJAX call:
$.ajax({
type: 'POST',
url: '#Url.Action("EkranBilgiListele")',
dataType: 'json',
data: { ids: arraySecilenEkranlarID },
success: function (data) {
console.log('---->' + data.ekranAd);
},
dataType: "json",
traditional: true
});
However, using breakpoints and results view always returns 'empty' and the console returns 'undefined'
Really sorry I wrote wrong query!
Writing right one.
public JsonResult EkranBilgiListele(List<int> ids)
{
//int[] ids = { 14, 16 }; ids comes like this
db.Configuration.ProxyCreationEnabled = false;
var secilenEkranlar = db.tbl_Ekranlar.Where(ekranlar => ids.Contains(ekranlar.ekranID));
return Json(secilenEkranlar);
}
ajax code, changed a little bit:
$.ajax({
type: 'POST',
url: '#Url.Action("EkranBilgiListele")',
dataType: 'json',
data: { ids: arraySecilenEkranlarID },
success: function (secilenEkranlar) {
$.each(secilenEkranlar, function (i, ekranlar) {
console.log(ekranlar.ekranAd);
});
},
error: function (ex) {
alert('İlçeler Çekilemedi.' + ex);
}
});

responseText always returns 'undefined' even though Im using asynchrous 'success' trigger

function WyslijRequestAjaxem(){
var pole1 = document.getElementById("data_albo_czas");
var url1 = "date_time_now.php";
alert(pole1.value);
alert("xd");
$.ajax({
url: url1,
type: "get",
dataType: "html",
data: { zmienna: pole1.value},
success: OdbierzResponse
})
}
function OdbierzResponse(response) {
var p = document.getElementById("pt1");
p.innerHTML = response.responseText;
}
In the case of a html dataType for jQuery's AJAX function, the first argument passed to the success callback is the responseText, so change your function to:
function OdbierzResponse(response) {
var p = document.getElementById("pt1");
p.innerHTML = response;
}
As explained in the docs this function is passed three arguments:
The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object.
If you need the actual jqXhr object to work with you'd need to do:
function OdbierzResponse(response, status, xhr) {
var p = document.getElementById("pt1");
p.innerHTML = response;
...
}
and use xhr to access the properties or methods that you require.
function WyslijRequestAjaxem() {
var pole1 = document.getElementById("data_albo_czas");
var url1 = "date_time_now.php";
alert(pole1.value);
alert("xd");
$.ajax({
url: url1,
type: "get",
dataType: "html",
data: {
zmienna: pole1.value
},
success: function (response) {
OdbierzResponse(response); // call OdbierzResponse function with parameter here
}
})
}
Try change
p.innerHTML = response.responseText;
to
p.innerHTML = response;

Resources