Returning a Javascript Promise from $.ajax call - javascript

I am attempting to cast a $.ajax() statement to an es6 Promise and return the es6 promise. The idea is that I will have an application layer of Create, Update, Delete calls to the Microsoft Dynamics Web API which return an es6 Promise so that I can reuse the Create, Update, Delete calls across multiple pages. I've read through the Google, MDN, and David Walsh Blog articles about es6 Promises as well as several SO questions, but I haven't been able to quite put together the details yet.
In my code below, when ExpenseUpload.js calls expenseTransactionSetAPI.Create(newExpenseTransactionSet).then(...)); I see the execution getting to the then(), but nothing inside the then() is being executed. I'm not quite sure what changes I need to make so that my code execution actually processes the then() and I'm not even sure if I am using es6 Promises correctly. Any guidance would be appreciated.
ExpenseUpload.js
"use strict";
requirejs.config({
bundles: {
'CCSEQ.WebAPI.js': ['Model/ExpenseTransaction', 'Model/ExpenseTransactionSet', 'API/ExpenseTransaction', 'API/ExpenseTransactionSet']
}
});
require(["Model/ExpenseTransaction", "Model/ExpenseTransactionSet", "API/ExpenseTransaction", "API/ExpenseTransactionSet"], function (ExpenseTransactionModel, ExpenseTransactionSetModel, ExpenseTransactionAPI, ExpenseTransactionSetAPI) {
let file;
$(document).ready(() => {
setupHandlers();
});
function setupHandlers() {
$("#csv-file").change((e) => {
file = e.target.files[0];
});
$("#btnUploadFile").click(() => loadFile());
}
function loadFile() {
Papa.parse(file, {
complete: (results) => {
ImportExpenseTransaction(results.data);
console.log("import complete");
}
});
}
function ImportExpenseTransaction(data) {
let newExpenseTransactionSet = new ExpenseTransactionSetModel.ExpenseTransactionSet();
newExpenseTransactionSet.SetName = $("#UploadName").val();
newExpenseTransactionSet.Month = $("#UploadMonth").val();
newExpenseTransactionSet.Year = $("#UploadYear").val();
newExpenseTransactionSet.ImportDate = new Date();
newExpenseTransactionSet.Status = 100000000;
let newExpenseTransactions = new Array();
data.forEach((expense) => {
if (expense[0] !== "PR EMP ID") {
let newRecord = new ExpenseTransactionModel.ExpenseTransaction();
newRecord. = expense[n];
... // Load other records like above
newExpenseTransactions.push(newRecord);
}
});
let expenseTransactionSetAPI = new ExpenseTransactionSetAPI.ExpenseTransactionSet();
let expenseTransactionAPI = new ExpenseTransactionAPI.ExpenseTransaction();
expenseTransactionSetAPI.Create(newExpenseTransactionSet).
then((data) => {
console.log(data);
console.log("Transaction Set Created");
expenseTransactionAPI.
Create(newExpenseTransactions[0]).
then(() => {
console.log("Transaction Created");
}).catch(() => {
console.log("failure");
});
}).catch(() => {
(data) => {
console.log(data);
console.log("failure");
}
});
}
});
CCSEQ.WebAPI.js
define("API/ExpenseTransaction", ["require", "exports", "API/APIBase", "Model/ExpenseTransaction"], function (require, exports, APIBase_1, Model) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ExpenseTransaction extends APIBase_1.APIBase {
constructor() {
super();
this.ConvertToEntity = (data) => {
let result = new Array();
for (let i = 0; i < data.length; i++) {
let newRecord = new Model.ExpenseTransaction();
newRecord.[field] = data[i]["fieldName"];
.
.
.
result[i] = newRecord;
}
return result;
};
}
Create(expense) {
return new Promise((resolve, reject) => {
$.ajax({
url: this.ExpenseTransaction,
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(expense.toJSON()),
success: (data) => { resolve(data); },
error: (data) => { reject(data); }
});
});
}
;
}
exports.ExpenseTransaction = ExpenseTransaction;
});
define("API/ExpenseTransactionSet", ["require", "exports", "API/APIBase", "Model/ExpenseTransactionSet"], function (require, exports, APIBase_2, Model) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class ExpenseTransactionSet extends APIBase_2.APIBase {
constructor() {
super();
this.ConvertToEntity = (data) => {
let result = new Array();
for (let i = 0; i < data.length; i++) {
let newRecord = new Model.ExpenseTransactionSet();
newRecord.[field] = data[i]["fieldName"];
.
.
.
result[i] = newRecord;
}
return result;
};
}
Create(expenseSet) {
return new Promise((resolve, reject) => {
$.ajax({
url: this.ExpenseTransactionSet,
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(expenseSet.toJSON()),
success: (data) => {
resolve(data);
},
error: (data) => {
reject(data);
}
});
});
}
;
}
exports.ExpenseTransactionSet = ExpenseTransactionSet;
});
//# sourceMappingURL=CCSEQ.WebAPI.js.map

Just return the ajax requests, it returns a promise-like Object.
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the
Promise interface, giving them all the properties, methods, and
behavior of a Promise
Create(expense) {
return $.ajax({
url: this.ExpenseTransactionSet,
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(expenseSet.toJSON())
});
}

Related

Returning data from a Promise

I have a function which I use to populate some fields at load, which looks like this:
function billingAddress(){
var urls = ['myURL'];
var output = [];
Promise.all(
urls.map(
u=>fetch(u).then(response => {
if (!response.ok) {
throw new Error("Http Error " + response.status);
}
return response.json();
})
)
).then(texts => {
fillAddress(texts);
var info = getCustomerInfo(texts);
console.log(info); //returns the data
output.push(info);
});
return output;
}
The fillAddress function just fills in the respective fields on document load. In order to place an order, I need to gather the customer info and send a post request to the server. What I don't understand is how I can save the information from getCustomerInfo so I can process it at a later time.
For your reference,
function getCustomerInfo(data){
var temp = data[0]['addresses']['shipping'];
var info = {};
info['address1'] = temp[0];
info['address2'] = temp[1];
info['city'] = temp[2];
info['zip'] = temp[3];
info['country'] = temp[4];
info['state'] = temp[5];
info['phone'] = temp[8];
info['gst'] = temp[9];
info['email'] = temp[10];
info['items'] = [];
return info;
}
Post function:
function placeOrder(){
var info = billingAddress();
console.log(info); //returns undefined
$.ajax({
url: 'placeOrder',
contentType: 'application/json',
type: 'POST',
dataType: 'json',
data: JSON.stringify(info),
success: function(data){
console.log(data);
}
});
}
placeOrder() is an onclick function, so I can't run it inside billingAddress()
You are getting your info data asynchronously, so you must access it asynchronously. What this means is that you can't return a value which is obtained from an asynchronous function call in a synchronous function, like you are trying to do with pushing info to output and then returning output. What is happening in your function is that output is being immediately returned as an empty array, while your asynchronous code executes in the background and then updates this array but only after it has already been returned. Instead, you should return a promise from your billingAddress function and access the data in the promise callback:
function billingAddress(){
var urls = ['myURL'];
return Promise.all(
urls.map(
u=>fetch(u).then(response => {
if (!response.ok) {
throw new Error("Http Error " + response.status);
}
return response.json();
})
)
).then(texts => {
fillAddress(texts);
return getCustomerInfo(texts);
});
}
function placeOrder(){
billingAddress().then(info => {
$.ajax({
url: 'placeOrder',
contentType: 'application/json',
type: 'POST',
dataType: 'json',
data: JSON.stringify(info),
success: function(data){
console.log(data);
}
});
});
}
Also, I would recommend using const or let instead of var and async/await to handle your promises, which will result in cleaner code:
async function billingAddress(){
try {
const urls = ['myURL'];
const texts = await Promise.all(
urls.map(u => {
const response = await fetch(u);
if (!response.ok) {
throw new Error("Http Error " + response.status);
}
return response.json();
})
);
return getCustomerInfo(fillAddress(texts));
} catch (e) {
// handle errors
}
}
async function placeOrder(){
try {
const info = await billingAddress();
$.ajax({
url: 'placeOrder',
contentType: 'application/json',
type: 'POST',
dataType: 'json',
data: JSON.stringify(info),
success: function(data){
console.log(data);
}
});
} catch (e) {
// handle errors
}
}

How would you automatically retry a failed ajax call 3 times (synchronously)?

I'm trying to rerun a failed AJAX call 3 times. After the third attempt, I'd like to call a failed method. I don't want the AJAX calls to over run each other though.
What's the safest/best way to achieve this with what I'm working with?
I'm using a globalAjaxRequest method like so:
globalAjaxRequest(request, successCallback, errorCallback) {
let ajaxRequest = null;
if (request.url) {
const ajaxOptions = {
type: request.method ? request.method.toUpperCase() : 'POST',
url: request.url,
data: request.data || undefined,
beforeSend: request.beforeSend,
success: (data) => {
successCallback(data);
},
error: (data) => {
if (errorCallback) {
errorCallback(data);
}
}
};
ajaxOptions.dataType = request.dataType || 'json';
ajaxOptions.contentType = request.contentType || 'application/json; charset=utf-8';
if (request.contentType) {
ajaxOptions.data = $.parseJSON(JSON.stringify(ajaxOptions.data));
} else {
ajaxOptions.data = JSON.stringify(ajaxOptions.data);
}
ajaxRequest = $.ajax(ajaxOptions);
}
return ajaxRequest;
}
}
Here's my attempt:
callAPI() {
const callData = {
url: '/callApi',
data: {
id: 'something'
}
};
global.Utils.globalAjaxRequest(callData, (success) => {
console.log('success');
successMethod();
}, (fail) => {
for (let i = 1;; i++) {
i <= 3 && setTimeout(() => {
callAPI();
}, 1000);
if (i > 3) {
failedMethod();
break;
}
}
});
}
callAPI();
You can't retry an asynchronous operation such as $.ajax() synchronously, so I'll assume that you just meant you want to automatically retry sequentially if it fails.
Here's a generic retry function for $.ajax():
// general purpose promise delay, useful when you want to delay a promise chain
function pDelay(t, v) {
return new Promise(function(resolve) {
setTimeout(resolve, t, v);
});
}
// three arguments:
// options: value for $.ajax(options) - does not support other forms of calling $.ajax()
// delay: amount of time in ms to delay before each retry (can be 0 if you want)
// retries: number of times to retry, defaults to 3 if you don't pass it
$.ajaxRetry = function(options, delay, retries) {
// default value for retries is 3 if the argument is not passed
let retriesRemaining = retriesRemaining !== undefined ? retriesRemaining: 3;
let opts = Object.assign({}, options);
function run() {
return $.ajax(opts).catch(function(err) {
--retriesRemaining;
// don't fire this more than once
delete opts.beforeSend;
if (retriesRemaining > 0) {
// try again after short delay
return pDelay(delay).then(run);
} else {
// hit max retries, propagate error back to caller
throw e;
}
});
}
return run();
}
FYI, this code assumes that "failure" in your case means that the promise that $.ajax() rejects. If "failure" means something else (such as looking at some result you got), then you will have to insert that additional test into the retry loop or expose a callback where that additional test can be provided externally.
To integrate this into your wrapper, you could do this:
globalAjaxRequest(request, successCallback, errorCallback) {
let ajaxRequest = null;
if (request.url) {
const ajaxOptions = {
type: request.method ? request.method.toUpperCase() : 'POST',
url: request.url,
data: request.data || undefined,
beforeSend: request.beforeSend,
};
ajaxOptions.dataType = request.dataType || 'json';
ajaxOptions.contentType = request.contentType || 'application/json; charset=utf-8';
if (request.contentType) {
ajaxOptions.data = $.parseJSON(JSON.stringify(ajaxOptions.data));
} else {
ajaxOptions.data = JSON.stringify(ajaxOptions.data);
}
errorCallback = errorCallback || function(err) { throw err; };
ajaxRequest = $.ajaxRetry(ajaxOptions, 0, 3).then(successCallback, errorCallback);
}
return ajaxRequest;
}
}
FYI, it is kind of odd to take a promise interface and turn it back into plain callbacks. It seems you should just get rid of successCallback and errorCallback let the caller use the returned promise.
I'd do something like this that uses a closure to keep a counter above the async request:
globalAjaxRequest(request, successCallback, errorCallback, maxRequests) {
maxRequests = maxRequests || 1;
var requests = 1;
function ajaxRequest(request){
if (request.url) {
const ajaxOptions = {
type: request.method ? request.method.toUpperCase() : 'POST',
url: request.url,
data: request.data || undefined,
beforeSend: request.beforeSend,
success: (data) => {
successCallback(data);
},
error: (data) => {
if (requests < maxRequests){
requests++;
ajaxRequest(request);
} else if (errorCallback) {
errorCallback(data);
}
}
};
ajaxOptions.dataType = request.dataType || 'json';
ajaxOptions.contentType = request.contentType || 'application/json; charset=utf-8';
if (request.contentType) {
ajaxOptions.data = $.parseJSON(JSON.stringify(ajaxOptions.data));
} else {
ajaxOptions.data = JSON.stringify(ajaxOptions.data);
}
return $.ajax(ajaxOptions)
}
ajaxRequest(request);
}

JavaScript Function ReEntrant in promise object

I would like to reentrant function in promise object.
this function contains Asynchronous processing.
however, this function dose NOT Work.
To be specified, DOES NOT fired ,next "then method".
the code is here
loopcount = 0;
getItemcount = 0;
global_ItemCol = [];
function GetItem_in_List_Over5000(parentSiteUrl, listGuid)
{
if (loopcount == 0) {
console.log("Enter FirstTime");
endPoint = parentSiteUrl + "/_api/Web/Lists(guid'" + listGuid + "')/Items?$top=3000&$select=Title,Id,ContentTypeId,HasUniqueRoleAssignments";
} else {
console.log("Eneter SecondTime");
}
return new Promise(function (resolve_GetItem_in_List5000, reject_GetItem_in_List5000) {
console.log("Eneter Inner Function");
$.ajax({
type: 'GET',
url: endPoint,
headers: { 'accept': 'application/json;odata=verbose', "X-RequestDigest": $("#__REQUESTDIGEST").val() },
success: function (data) {
console.log(data.d.__next);
if (data.d.__next) {
global_ItemCol = global_ItemCol.concat(data.d.results);
endPoint = data.d.__next;
loopcount++;
console.log("looopcount increment. " + global_ItemCol.length);
GetItem_in_List_Over5000(parentSiteUrl, listGuid);
} else {
global_ItemCol = global_ItemCol.concat(data.d.results);
var local_col = [];
local_col = local_col.concat(global_ItemCol);
loopcount = 0;
global_ItemCol.length = 0;
resolve_GetItem_in_List5000(local_col);
console.log("return call");
//return Promise.resolve().then(local_col);
resolve_GetItem_in_List5000(local_col);
}
},
error: function (error) {
OutputLog(error.responseJSON.error.message.value);
loopcount = 0;
reject_GetItem_in_List5000();
}
});
});
}
I called this function Added Array and Promise.All().
Thanks in advance.
You could try a recursive function. Store results in an array (not global but pass it to the recursive function). With every result set store the guid so you know what result set came from what guid (when requests start failing you know what you've done so far).
function GetItem_in_List_Over5000(parentSiteUrl, listGuid) {
const recur = (listGuid,results=[]) =>
$.ajax({
type: 'GET',
url: parentSiteUrl + "/_api/Web/Lists(guid'" + listGuid + "')/Items?$top=3000&$select=Title,Id,ContentTypeId,HasUniqueRoleAssignments",
headers: { 'accept': 'application/json;odata=verbose', "X-RequestDigest": $("#__REQUESTDIGEST").val() },
}).then(
function (data) {
console.log(data.d.__next);
if (data.d.__next) {
return recur(
data.d.__next,
results.concat([listGuid,data.d.results])
);
} else {
//add listGuid to result set so you know where it came from
return results.concat([listGuid,data.d.results]);
}
}
).fail(//newer jQuery can use .catch
err=>({type:"error",error:err,results:results})
);
return recur(listGuid)
}
GetItem_in_List_Over5000("url","guid")
.then(
results=>{
if((results&&results.type)===error){
console.log("something went wrong:",results.error);
console.log("have some results:",results.results);
}else{
console.log("got all results:",results);
}
}
)

Second promise is not working properly

I have the following promise that works perfectly:
self.getAll = function (callback) {
var users= [];
var promises = [];
$.ajax({
url: "/API/Users",
type: "GET",
success: function (results) {
var mappedContacts = $.map(results, function (item) {
promises.push($.ajax({
url: "/API/Users/contacts/" + item.id,
type: "GET"
}).then(function (contacts) {
users.push(new User(item, contacts));
}));
});
$.when.apply($, promises).then(function () {
callback(users);
});
}
});
}
I'm trying to add a second AJAX request but it's not working properly:
self.getAll = function (callback) {
var users= [];
var promises = [];
$.ajax({
url: "/API/Users",
type: "GET",
success: function (results) {
var mappedContacts = $.map(results, function (item) {
promises.push($.ajax({
url: "/API/Users/contacts/" + item.id,
type: "GET"
}).then(function (contacts) {
users.push(new User(item, contacts));
}));
});
var mappedContacts2 = $.map(results, function (item) {
promises.push($.ajax({
url: "/API/Users/contacts2/" + item.id,
type: "GET"
}).then(function (contacts2) {
users.push(new User(item, "",contacts2));
}));
});
$.when.apply($, promises).then(function () {
callback(users);
});
}
});
}
contacts2 is always empty, what am I doing wrong?
This is the User object:
var User= function (data, contacts, contacts2) {
this.id = ko.observable(data.id);
this.name = ko.observable(data.name);
this.contacts = ko.observableArray(contacts);
this.contacts2 = ko.observableArray(contacts2 );
}
Since you need both sets of contacts for each user to pass to new User() use one map() that returns a $.when() for both contacts requests. Create the user in then() of that $.when()
Something like:
self.getAll = function(callback) {
var users = [];
// return this promise ..... see notes below
return $.getJSON("/API/Users").then(results) {
// map array of promises to pass to final $.when
var promises = $.map(results, function(item) {
var req1 = $.getJSON("/API/Users/contacts/" + item.id);
var req2 = $.getJSON("/API/Users/contacts2/" + item.id);
// return this promise to mapped array
return $.when(req1, req2).then(function(contacts1, contacts2) {
// create user now that we have both sets of contacts
users.push(new User(item, contacts1, contacts2));
});
})
// should return this promise .... see notes below
return $.when.apply($, promises).then(function() {
callback(users);
// return `users` ...see notes below
});
})
}
Using a callback is an outdated approach when you could just return the promise chain shown in comments above and do :
self.getAll().then(function(users) {
// do something with users
})

Know if operation succeeded or rejected with promises

I have a main function where I want to check if a record exists or not in order to create or update the record, so in this function I am calling a helper function that checks for that record using ajax call, and then I want a true/false to be returned to the main function, but do I return defrred.resolve() and deferred.reject(), and how do I check on them? I can't seem to be able to implement it in promises.
Here's my code below, any hint is appreciated.
function _mainFunction()(
var recordID = prompt("Enter Desired Record ID");
var promise = _helperFunction(recordID);
promise.then(...) //do some processing when the reocrd is created or updated
)
function _helperFunction(passedId){
if (passedId) {
if (!_isRecordExists(passedId)) {
// if record doesn't exist, create it.
}
}
}
function _isRecordExists(passedId){
var decision;
var baseUrl = "some url";
var dfd = $.ajax({
url: baseUrl,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
});
dfd.promise().then(
function(data, status, jqXHR){
decision = true;
dfd.resolve();
},
function (jqXHR, status, error) {
decision = false;
dfd.reject();
});
return decision; // do I return decision here for true or false?
}
}
You need to return promise object from _isRecordExists function. Then in _helperFunction if-block wouldbe transformed into success/error callbacks of the promise returned from the previous check:
function _mainFunction() {
var recordID = prompt("Enter Desired Record ID");
var promise = _helperFunction(recordID);
promise.then(function() {
console.log('Do something else');
}, function() {
console.log('Failed to find and create new. Maybe try again');
});
}
function _helperFunction(passedId) {
return $.Deferred(function(deferred) {
if (passedId) {
_isRecordExists(passedId).then(function(recordObj) {
// record exists, do something with it
console.log('Exists');
deferred.resolve(recordObj);
}, function() {
// record doesn't exist, create it.
console.log('Does not exist');
deferred.reject();
});
}
deferred.reject();
}).promise();
}
function _isRecordExists(passedId) {
var decision;
var baseUrl = "some url";
return $.ajax({
url: baseUrl,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
});
}
Here is also a rewritten _helperFunction implemented with a real promises (either with a polyfill or native):
function _helperFunction(passedId) {
if (passedId) {
return Promise.resolve(_isRecordExists(passedId)).then(function(recordObj) {
// record exists, do something with it and pass further
return recordObj;
}, function() {
// record doesn't exist, create it
return createNewRecord(); // createNewRecord should return new promise
});
}
return Promise.reject();
}
function _mainFunction(){
var recordID = prompt("Enter Desired Record ID");
_helperFunction(recordID)
.then(function(decision) {
// you can use decision here
})
.catch(function(decision) {
// passing decision as true or false in _isRecordExists fn, just for information
// or future usages
// then / catch status already gives the idea
});
}
function _helperFunction(passedId){
var deferred = $.deferred();
if (passedId) {
_isRecordExists(passedId))
.then(function(data) {
// then means exists : do whatever you want here
// if you want to return the result as promise;
deferred.resolve(data);
})
.catch(function(errorData) {
// catch means does not exist : create or do anything
deferred.reject(errorData);
});
} else {
// no id provided
deferred.reject();
}
return deferred.promise();
}
function _isRecordExists(passedId){
var decision;
var baseUrl = "some url";
var dfd = $.ajax({
url: baseUrl,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
});
return dfd.promise().then(
function(data, status, jqXHR){
decision = true;
dfd.resolve(decision);
},
function (jqXHR, status, error) {
decision = false;
dfd.reject(decision);
});
}
}
Syntax errors at function _mainFunction()( , close of _mainFunction() at ) ; jQuery promise object not returned from _helperFunction
function _mainFunction() {
var recordID = prompt("Enter Desired Record ID");
var promise = _helperFunction(recordID);
promise.then(function success(t) {
// resolved
console.log(t)
}, function err(e) {
// rejected
console.log(e)
})
//do some processing when the reocrd is created or updated
}
function _helperFunction(passedId) {
if (passedId) {
// return `_isRecordsExists`
return _isRecordExists(passedId)
.then(function(data) {
return data
}, function err(data) {
return data
})
} else {
// if `passedId` not entered, return rejected deferred
return $.Deferred().reject("no passedID")
}
}
function _isRecordExists(passedId) {
var decision;
var baseUrl = "some url";
// do asynchronous stuff
// var dfd = $.ajax({
// url: baseUrl,
// type: "GET",
// contentType: "application/json;odata=verbose",
// headers: {
// "accept": "application/json;odata=verbose"
// }
// });
var dfd = $.Deferred(function(d) {
setTimeout(function() {
d.resolve()
}, Math.random() * 2000)
});
// return `dfd` promise here
return dfd.promise().then(
function(data, status, jqXHR) {
decision = true;
return decision
},
function(jqXHR, status, error) {
decision = false;
return decision
})
// return dfd.promise();
// do I return decision here for true or false?
}
_mainFunction()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
function _mainFunction() {
var recordID = prompt("Enter Desired Record ID");
var promise = _helperFunction(recordID);
promise.then(...) //do some processing when the reocrd is created or updated
}
function _helperFunction(passedId){
if (passedId) {
if (!_isRecordExists(passedId)) {
// if record doesn't exist, create it.
}
}
}
function _isRecordExists(passedId){
var decision;
var baseUrl = "some url";
var dfd = $.ajax({
url: baseUrl,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
});
dfd.promise().then(
function(data, status, jqXHR){
decision = true;
dfd.resolve();
},
function (jqXHR, status, error) {
decision = false;
dfd.reject();
});
return decision;
// do I return decision here for true or false?
// answer: NO!!, before the value(true or false) is assigned to decision, decision is returned...(Of course, the value may be allocated and then return). The Promise object should return to the place where the actual value is used.
}
}
// here is my answer
function _mainFunction(passedId){
var recordID = prompt("Enter Desired Record ID");
isExistPromise = _isRecordExists(recordID);
isExistPromise.then(function(data){
if (data.isExist) {}
else {}
});
}
function _isRecordExists(passedId){
var decision;
var baseUrl = "some url" + passedId;
return $.ajax({
url: baseUrl,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
});
}
then I want a true/false to be returned to the main function
You can't return true/false to the main function because by the time your code finish execute, the promise is still working and does not have a result yet, hence your _mainFunction does not know if it should return true or false.
What you can do is return a Promise in _mainFunction and then use .then or .fail to do your logic code.
function _mainFunction()(
var recordID = prompt("Enter Desired Record ID");
var promise = _helperFunction(recordID);
promise.then(function (result) {
if (result == true) {
// Do something
} else {
// Do something else
}
})
)
function _helperFunction() {
return $.ajax(...)
.then(function (response) {
if (...) {
return true;
} else {
return false;
}
});
}
From what I observe in your code, I think you should really spend sometime on learning how to work on asynchronous programming in JavaScript.
These are the helpful links that you might want to read:
Asynchronous JavaScript Programming
An introduction to jQuery Deferred / Promise and the design pattern in general

Categories