Why is my code not waiting for the promises to complete? - javascript

I have the following code making multiple AJAX calls (by calling ExecuteServiceMethod) in an jquery "each" loop. I'd like to wait for all the calls to complete before calling the "__doPostBack", but it doesn't seem to be working and the postback gets called before all the ajax calls return.
Here's the calling code:
$("table[id*=ChangeAllGridView]").on("hide.bs.dropdown", ".dropdown.bootstrap-select", function (event) {
var LotID = '<%=Session[ID + "EditedLot"]%>';
var SplitsList = $(event.target).children("button.dropdown-toggle").attr("title");
var SplitsArray = $(event.target).children("select").val();
var promises = [];
$(".selectpicker[id*=SplitDropDown]").not("[id*=SplitDropDown_All]").each(function () {
$(this).selectpicker("val", SplitsArray);
var WID = $(this).attr("id").split("_")[3];
var a = ExecuteServiceMethod("LotEditorWebService.asmx", "UpdateWaferSplits", ["LotID", LotID, "WID", WID, "SplitsList", SplitsList], function () { });
promises.push(a);
});
Promise.all(promises).then(function () {
__doPostBack($(event.target).attr('id'), '');
});
});
And here's the ExecuteServerMethod routine making the AJAX call:
function ExecuteServiceMethod(page, fn, paramArray, successFn, errorFn) {
var paramList = '';
if (paramArray.length > 0) {
for (var i = 0; i < paramArray.length; i += 2) {
if (paramList.length > 0) paramList += ',';
paramList += '"' + paramArray[i] + '":"' + paramArray[i + 1] + '"';
}
}
paramList = '{' + paramList + '}';
return $.ajax({
type: "POST",
url: page + "/" + fn,
contentType: "application/json; charset=utf-8",
data: paramList,
dataType: "json",
success: successFn,
error: errorFn
});
}
I've tried a number of iterations of this, including putting a "new Promise()" statement around the AJAX call and returning that, but nothing seems to help.
Would appreciate your help on this.
Thanks.

try wrapping like this: Promise.resolve($.ajax(...))
edit: you can also try removing the success and error callbacks in the ajax function
edit edit: also try catching any errors on your Promise.all

Related

javascript execute nested ajax call inside a for loop

So, I have two code snippets - both of them are executing without errors. Both are meant to do the same thing - loop through a list of words and look up documents these words appear in (SOLR), then pull paragraphs where these words appear from each document. However they don't return the desired result. The first one skips over the nested ajax call (the one inside the for each loop) and if runs the ajax call at all, it's after the main (parent) loop already finished. The second one only works properly if there is an alert there. If the user acknowledges the alert, then the second loop executes correctly. Without the alert, the second loop gets skipped. Can anyone shed some light at what is wrong here. I've tried ajax {complete:...} and ajax{}.done but they didn't work either.
Here is the first snippet:
for (var m = 0; m < definitions.length; m++ ) {
var url = pathtomyfile;
var doctitle, docname, docs;
var htmlBody, pHtml, fullHTML;
$.ajax({
url: url,
async: false,
dataType: 'json',
success: function (result){
docs = result.response.docs;
},
complete: function () {
$(docs).each (function (){
var doctitle = this.dc_title_str.toString().replace (/(\.html|\.htm)/, '');
var docname = filePathToUrl (this.resourcename.toString ());
var url = decodeURIComponent (docname);
$.ajax({
url: url,
async: false,
dataType: 'html',
success: function (resp){
fullHTML = resp.toString();
htmlBody = fullHTML.split (/<body>/)[1].split (/<\/body>/)[0];
htmlBody = htmlBody.replace (/\s/g, " ").replace (/ /g, " ").replace (/(<a id="x\d+?")\/>/g, "$1></a>");
var pHtml = $(htmlBody).find("#id").parent();
pHtml = $(pHtml).wrap('<p/>').parent().html();
pHtml = pHtml.replace (/\<a id/g, "#s#").replace (/<\/a>/g, "#e#").replace (new RegExp ("\\b(" + en_word.replace (/\s/g, "(<[^<]+?>| )*")+"(s|ed|ing|es)*)\\b", "ig"), "<span style='background-color:yellow'>$1</span>").replace (/#s#/g, "<a id").replace (/#e#/g, "<\/a>");
hsnip += "<p><b><i>From " + doctitle + ":</i></b></p> " + pHtml;
}
});
})
}
});
}
this is the second snippet:
for (var m = 0; m < definitions.length; m++ ) {
var url = pathtomyfile;
var doctitle, docname, docs;
var htmlBody, pHtml, fullHTML;
$.ajax({
url: url,
async: false,
dataType: 'json',
success: function (result){
docs = result.response.docs;
}
});
alert ('ok');
for (var b = 0; b < docs.length; b ++) {
doctitle = docs[b].dc_title_str.toString().replace (/(\.html|\.htm)/, '');
docname = filePathToUrl (docs[b].resourcename.toString ());
var rawFile = new XMLHttpRequest ();
docname = decodeURIComponent (docname);
rawFile.open ("GET", docname, false);
rawFile.onreadystatechange = function () {
if (rawFile.readyState === 4 && (rawFile.status === 200 || rawFile.status === 0)) {
fullHTML = rawFile.responseText.toString();
htmlBody = fullHTML.split (/<body>/)[1].split (/<\/body>/)[0];
var pHtml = $(htmlBody).find("#id").parent();
pHtml = $(pHtml).wrap('<p/>').parent().html();
hsnip += "<p><b><i>From " + doctitle + ":</i></b></p> " + pHtml;
}
}
rawFile.send (null);
}
}
This sounds like an async problem, is not the best idea to make AJAX calls in a loop, you can replicate a loop with recursivity though, have the function only make one call, and call the function again when each call is finished, and add a breakpoint with an if that checks if you're finished.

Sending a variable with ajax call .done

Is there a possible way to send the variable, 'schedule_id[i]', with the result of the call. Also is it possible to add this variable in the data object?
My code:
for (var i = 0; i < schedule_id.length; i++) {
//Ajax call
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id[i] + "?key=" + api_key
})
//
.done(function(data){
}
So you need asynchronies ajax call in synchronies manner right?
So you need to create one separate function which is call ajax request and return the result and use in subsequent request.
Like:-
for (var i = 0; i < schedule_id.length; i++) {
var result;
if (i == 0)
result = callfunction(0,schedule_id[i]);
else
result = callfunction(result,schedule_id[i]);
}
function callfunction(passresult,schedule_id) {
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id + "?key=" + api_key
})
.done(function (data) {
return data;
});
}
construct the ajax call like this:
$.ajax({
url: 'http://api.viewer.zmags.com/schedules/',
type: 'POST' // or GET,
data: {
schedule_ids: schedule_id, //array
key: api_key
},
success: function (data) {
//success callback
}
});

Uncaught ReferenceError: error is not defined in Ajax Callback

In my App, I get a list of Events from a Sharepoint Calendar List. That part works perfectly.
However after I get the collection of results, for each item I need to get the Display Form Url, which is another REST Call with the ListItem ID.
However I get the error below, but I still dont know what the problem might be
Uncaught ReferenceError: error is not defined App.js:87(anonymous function) App.js:87$.ajax.error App.js:40c jquery-1.9.1.min.js:22p.fireWith jquery-1.9.1.min.js:22k jquery-1.9.1.min.js:24send.r
I based my code on this answer:
https://sharepoint.stackexchange.com/questions/119236/how-to-get-the-display-form-url-using-rest
My adapted code is like this:
var SPHostUrl;
var SPAppWebUrl;
var ready = false;
// this function is executed when the page has finished loading. It performs two tasks:
// 1. It extracts the parameters from the url
// 2. It loads the request executor script from the host web
$(document).ready(function () {
var params = document.URL.split("?")[1].split("&");
for (var i = 0; i < params.length; i = i + 1) {
var param = params[i].split("=");
switch (param[0]) {
case "SPAppWebUrl":
SPAppWebUrl = decodeURIComponent(param[1]);
break;
case "SPHostUrl":
SPHostUrl = decodeURIComponent(param[1]);
break;
}
}
// load the executor script, once completed set the ready variable to true so that
// we can easily identify if the script has been loaded
$.getScript(SPHostUrl + "/_Layouts/15/SP.RequestExecutor.js", function (data) {
ready = true;
getItems();
});
});
function getListItemFormUrl(webUrl, listName, listItemId, formTypeId, complete, failure) {
$.ajax({
url: webUrl + "/_api/web/lists/GetByTitle('" + listName + "')/Forms?$select=ServerRelativeUrl&$filter=FormType eq " + formTypeId,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var url = data.d.results[0].ServerRelativeUrl + '?ID=' + listItemId
complete(url);
},
error: function (data) {
failure(data);
}
});
}
// this function retrieves the items within a list which is contained within the parent web
function getItems() {
// only execute this function if the script has been loaded
if (ready) {
// the name of the list to interact with
var listName = "Events";
// the url to use for the REST call.
var url = SPAppWebUrl + "/_api/SP.AppContextSite(#target)" +
// this is the location of the item in the parent web. This is the line
// you would need to change to add filters, query the site etc
// "/web/lists/getbytitle('" + listName + "')/items?" +
"/web/lists/getbytitle('" + listName + "')/items?$select=Title,Category,EventDate,Description,EncodedAbsUrl,ID" +
"&#target='" + SPHostUrl + "'";
// create new executor passing it the url created previously
var executor = new SP.RequestExecutor(SPAppWebUrl);
// execute the request, this is similar although not the same as a standard AJAX request
executor.executeAsync(
{
url: url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
// parse the results into an object that you can use within javascript
var results = JSON.parse(data.body);
var events = [];
$.each(results.d.results, function (i, obj) {
//Usage
getListItemFormUrl(SPAppWebUrl, 'Calendar', obj.ID, 4,
function (url) {
console.log('Display from url for list item: ' + url);
},
function (sender, args) {
console.log(JSON.stringify(error));
})
//use obj.id and obj.name here, for example:
var event = {
date: Date.parse(obj.EventDate).toString(),
type: obj.Category,
title: obj.Title,
description: obj.Description,
url: obj.EncodedAbsUrl + 'DispForm.aspx?ID=' + obj.ID
}
events.push(event);
});
var myJsonString = JSON.stringify(events);
$("#eventCalendarInline").eventCalendar({
jsonData: events,
openEventInNewWindow: true,
showDescription: true,
txt_GoToEventUrl: "Go to event"
});
Communica.Part.init();
},
error: function (data) {
// an error occured, the details can be found in the data object.
alert("Ooops an error occured");
}
});
}
}
Under //Usage:
function (sender, args) {
console.log(JSON.stringify(error));
})
error does not seem to be defined

Return a value using ajax and javascript

Sorry this must be a very simple question.
on the following code
var myFunction = function (city){
var totaljobs =null;
$.ajax({
url: "/EN/taleo/GetTotalJobs",
type: 'GET',
contentType: 'application/json',
dataType: 'json',
cache: false,
data: { value: city },
success: function (result) {
var JobsHTML = "";
for (count = 0; count < result.length; count++) {
JobsHTML += "<p>" + result[count]["JobTitle"] + "</p>"; //your fields here
}
totaljobs = JobsHTML;
/* alert(totaljobs);*/
}
});
return totaljobs;
}
i am trying to return the totaljobs value with all the jobHTML info. But all I am getting is NULL. Can someone tell me where I am going wrong.
Many thanks in advance
Hesh
You need to make a synchronous call to the service.
try using this option :
async : false
This might work..

$.ajax json method does not hit the web method

When this function is hit , it does not call my function in code behind? Why could it be doing this? How can I fix this error.
$(document).ready(function() {
$('[id$=btn_Update]').click(function() {
var reten = $('[id$=txt_Reten]').val();
var i=0;
var selectValues = "";
var ProdID = new Array();
$("#lst_ProdId option").each(function() {
selectValues = selectValues + $(this).text() + ",";
ProdID[i] = $(this).text();
i++;
});
for(var j=0; j < ProdID.length;j++)
{
// alert(ProdID[j]);
}
var params = "{'ProdID':'" + ProdID + "','RetenP':'" + reten + "'}";
$.ajax({
type: "POST",
url: "/ProductPricing/Products/RetenPeriod.aspx/UpdateRetenPeriod",
data: params,
contentType: "application/json; charset=utf-8",
datatype: "json",
success: function(result) {
alert("sucess");
},
error:function(e) {
alert(e.statusText);
// if(errorThrown != null)
// alert(textStatus+ ":"+errorThrown);
// else
// alert("fail");
}
});
return false;
});
return false;
});
This is my webmethod in code behind:
[WebMethod]
public static bool UpdateRetenPeriod(string[] ProdID,string RetenP)
{
for (int i = 0; i < ProdID.Length; i++)
{
update(ProdID[i],RetenP);
}
return true;
}
You're passing your parameters as a string instead of as an object literal:
var params = "{'ProdID':'" + ProdID + "','RetenP':'" + reten + "'}";
should (almost certainly) be:
var params = {'ProdID': ProdID,'RetenP': reten};
Also, how do you know that the ajax request is not making it to the server? Have you tried tracing the HTTP requests with something like TamperData (for Firefox) or Firebug (also Firefox)?
Does it call the error method?
You need to return JSON. Not a boolean. Perhaps something like {success: true}.
Then:
success: function(data) {
if(data.success) {
...
}
else {
...
}
}
jQuery expects JSON and will throw an error if it doesn't receive well-formed JSON. Also, what is the exact response you're getting back? You can use something like Firebug to figure this out.
One more thing. Can you verify that you can successfully hit that URL? Are you able to successfully point your browser to http://your.url.here/ProductPricing/Products/RetenPeriod.aspx/UpdateRetenPeriod?
Also look at Pointy's solution. Your request is unlikely to succeed since you aren't passing in an actual object literal.
Do you have a ScriptManager defined in the markup with EnablePageMethods set to true?
Also, I believe your params line should be:
var params = "{ProdID:'" + ProdID + "', RetenP:'" + reten + "'}";
I have several functions in my own apps that do it this way. You want the value of params to look like this: "{ProdID:'1,2', RetenP:'undefined'}"
Can you place a breakpoint at alert(e.statusText); to see what the error message is?
Have u got error message.. please, try to get the error message
I think, u can use this by replacing error block
error:
function(XMLHttpRequest, textStatus, errorThrown){
alert( "Error Occured!" + errorThrown.toString());
}
I think, problems occurred in code behind method.. if in [web method] has any problem, then ajax doesn't call the method..

Categories