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);
}
}
)
Related
I'm trying to make a Tampermonkey script to update dates on some site.
I got an array of id's from a site, and I'm requesting data from it with the id of the array. After that, I have to return data of each Input.
As the function is async, it returns data in a random order, but I need those new arrays to return in the original order. I have tried sync and Promises, but the first is too slow and I haven't understood the second.
I can sort ids, but I also got the dates which are in the order of the first Array, so I don't know how to achieve the same order as the second id array.
Here's the code:
id = GM_getValue('id');
for (let i = 0; i < id.length; i++) {
setTimeout(() => {
console.log("Updating " + (i + 1) + " Title");
GM_xmlhttpRequest({
method: "GET",
url: "***" + id[i] + "/***",
onload: function(response) {
$(response.responseText).find("#main-form :input").each(function(x) {
if (x == 0) ids.push(parseInt($(this).val()));
if (x == 1) array.push($(this).val()));
});
}
});
}, i * 333);
}
You can use Promises to execute the GET requests in a specific order. Here's an example:
id = GM_getValue('id');
function makeGetRequest(url) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: function(response) {
resolve(response.responseText);
},
onerror: function(error) {
reject(error);
}
});
});
}
for (let i = 0; i < id.length; i++) {
console.log("Updating " + (i + 1) + " Title");
try {
const response = await makeGetRequest("***" + id[i] + "/***");
$(response).find("#main-form :input").each(function(x) {
if (x == 0) ids.push(parseInt($(this).val()));
if (x == 1) array.push($(this).val());
});
} catch (error) { // in case the GET request fails
console.error("Request failed with error code", error.status, ". Message is ", error.responseText);
}
}
In this example, I've created a makeGetRequest() function with returns a promise, which is resolved on GET success, but rejected on failure.
await waits for the Promise to settle before moving on and the try exists to catch Promise rejection (if the GET fails).
References:
Promise on MDN.
await on MDN.
TypeScript:
export enum HttpDataType {
JSON = "JSON"
}
import {HttpDataType} from "./enum/HttpDataType";
export default class Http {
static get(option: { url: string, dataType?: HttpDataType, synchronous?: boolean, onload?: Function }) {
option['method'] = 'GET';
if (option.synchronous) {
return new Promise((resolve, reject) => {
// #ts-ignore
GM_xmlhttpRequest({
...option,
onload: (response) => {
resolve(option.dataType === HttpDataType.JSON ? JSON.parse(response.responseText) : response.responseText);
},
onerror: (error) => {
reject(error);
}
});
})
} else {
const onload1 = function (details) {
let response;
if (option.dataType === HttpDataType.JSON) {
response = JSON.parse(details.responseText);
} else {
response = details.response;
}
option.onload(response);
}
// #ts-ignore
GM_xmlhttpRequest({...option, onload: onload1});
}
}
}
static async getXxx() {
let response = await Http.get({
url: '……',
dataType: HttpDataType.JSON,
synchronous: true
});
// #ts-ignore
if (!response || response.status !== 'success') {
console.error('getXxx error', response);
}
// #ts-ignore
return response.data;
}
this.getXxx().then((data: any) => {
// ……
});
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);
}
I am trying to create a dictionary object of the response json's using postman's pm api sendRequest.
Wrote a recursive function to get all the responses but the problem is the response dictionary object population happens way before even the response comes back.
Is there any way to wait the dictionary population before each of the respective response is received so as to capture the response within the dictionary object ?
var respDictionary = {};
getResponses (listOfUrls);
console.log("respDictionary: ");
console.log(respDictionary);
function getResponses(urlList) {
if (typeof urlList === 'string') {
urlList = urlList.split(' ');
}
_url = urlList[0];
var call = {
url: _url ,
method: 'GET',
header: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
urlList.splice(0, 1);
pm.sendRequest(
call,
function (err, res) {
if (err) {
console.log(err);
} else {
if (urlList.length === 0) {
return;
}
try {
respDictionary[_url] = res.json();
} catch (e) {
console.log(err);
}
getResponses(urlList);
}
});
console.log(respDictionary);
}
Output is:
respDictionary:
Object:{}
//further, pm request responses are listed
You do not understand JavaScript asynchrounous handling. Maybe the following will help:
Event loop video
Promises
Event loop documentation (video is easier)
Your code will work if you use promises:
function getResponses(urlList) {
if (typeof urlList === 'string') {
urlList = urlList.split(' ');
}
return Promise.all(
urlList.map(
function(url){
return {
url: url ,
method: 'GET',
header: {
//not sure where token comes from
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
}
).map(
function(call){
return new Promise(
function(resolve,reject){
pm.sendRequest(
call,
function (err, res) {
if (err) {
reject(err);
} else {
resolve([call.url,res.json()]);
}
});
}
)
.then(
undefined
,function(err){
//if something goes wrong we will still return something
return [call.url,{error:err}];
}
)
}
)
)
.then(
function(results){
return results.reduce(
function(acc,result){
acc[result[0]] = result[1];
}
,{}
);
}
)
}
getResponses (listOfUrls)
.then(//this will always succeed, failed items have {error:something}
function(results){
console.log("results:",results);
}
);
console.log("this comes before results");
The code above will cause all request to happen at once, this may not be the desired behavior, I have written a throttle method that is part of some library functions that may come in handy. You can apply the throttle to your code so it will only have max amount of connections:
const max = 10;//maximum 10 active connections
function getResponses(urlList) {
const throttled = throttle(max);
if (typeof urlList === 'string') {
urlList = urlList.split(' ');
}
return Promise.all(
urlList.map(
function(url){
return {
url: url ,
method: 'GET',
header: {
//not sure where token comes from
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
}
).map(
throttled(//only max amount of connections active at any time
function(call){
return new Promise(
function(resolve,reject){
pm.sendRequest(
call,
function (err, res) {
if (err) {
reject(err);
} else {
resolve([call.url,res.json()]);
}
});
}
)
.then(
undefined
,function(err){
//if something goes wrong we will still return something
return [call.url,{error:err}];
}
)
}
)
)
)
.then(
function(results){
return results.reduce(
function(acc,result){
acc[result[0]] = result[1];
}
,{}
);
}
)
}
getResponses (listOfUrls)
.then(//this will always succeed, failed items have {error:something}
function(results){
console.log("results:",results);
}
);
console.log("this comes before results");
Apart from the other answer(s), following simple approach also works well instead of recursion:
_.forEach (
urls,
function (urls) {
getAPI(url,function (url,schema,err) {
if (!err) {
respDictionary[url]=resp.json();
console.log(schema);
} else {
console.log(err);
}
pm.environment.set('respDictionary', JSON.stringify(respDictionary));
});
}
);
function getAPI(url, callback) {
var _url = '{{BP_SERVER}}/' + urls;
var call = {
url: _url,
method: 'GET',
header: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
pm.sendRequest(
call,
function (err, res) {
if (!err) {
callback(urls,res.json());
} else {
callback(urls,'',err);
}
}
);
}
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
I'm trying to use promise to return a comparison of current logged in user and a field from a list in SharePoint.
function compareCurrentUserWithListObject() {
var userProp = this._userProfileProperties;
var userName = userProp.get_userProfileProperties()['UserName'];
return this._list.filter(function (element, index, array) {
var promise = jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/GetUserById(" + element.user.get_lookupId() + ")",
type: "GET",
headers: { "Accept": "application/json;odata=verbose" }
});
promise.done(function(data) {
return (data.d.Email.indexOf(userName) > -1);
});
});
}
function init() {
var userArray = this.compareCurrentUserWithListObject();
userArray.done(function(res) {
if (res.length > 0) {
//Do some stuff after compare...
}
});
}
I'm not sure I'm using the .done correct here. Can someone help me?
EDIT:
Working code:
function compareCurrentUserWithListObject() {
var userProp = this._userProfileProperties;
var userName = userProp.get_userProfileProperties()['UserName'];
return this._list.filter(function (element, index, array) {
var promise = jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/GetUserById(" + element.user.get_lookupId() + ")",
type: "GET",
headers: { "Accept": "application/json;odata=verbose" }
});
promise.done(function(data) {
return (data.d.Email.indexOf(userName) > -1);
});
return promise;
});
}
function init() {
var userArray = this.compareCurrentUserWithListObject();
if (userArray.length > 0) {
//Do some stuff after compare...
}
}
you need to return the promise
function compareCurrentUserWithListObject() {
var userProp = this._userProfileProperties;
var userName = userProp.get_userProfileProperties()['UserName'];
return this._list.filter(function (element, index, array) {
var promise = jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/GetUserById(" + element.user.get_lookupId() + ")",
type: "GET",
headers: { "Accept": "application/json;odata=verbose" }
});
promise.done(function(data) {
return (data.d.Email.indexOf(userName) > -1);
});
// return promise here
return promise;
});
}
or this (which is cleaner IMO):
function compareCurrentUserWithListObject() {
var userProp = this._userProfileProperties;
var userName = userProp.get_userProfileProperties()['UserName'];
return jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/GetUserById(" + element.user.get_lookupId() + ")",
type: "GET",
headers: { "Accept": "application/json;odata=verbose" }
});
}
function init() {
this.compareCurrentUserWithListObject()
.done(function(data) {
var res = data.d.Email.indexOf(userName) > -1;
if (res.length > 0) {
//Do some stuff after compare...
}
});
}
it looks like you want to modify the response before using it in init. There is a way to do that but I'd do it inside the .done callback when using it.
I didn't test this code so there might be mistakes. But the general answer is: you need to return the promise.
The idiomatic way to do this using promises is to use Promise.all(). (I'll use Q promises as an example, but Promise.all is built into the JS6 promise API and several other promise libraries):
function getUserInfo(listItem) {
var promise = jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl +
"/_api/web/GetUserById(" + listItem.user.get_lookupId() + ")",
type: "GET",
headers: { "Accept": "application/json;odata=verbose" }
});
return Q.Promise.when(promise);
}
function filterUsers(users) {
var userProp = this._userProfileProperties;
var userName = userProp.get_userProfileProperties()['UserName'];
return users.filter(function (user) {
return user.d.Email.indexOf(userName) > -1;
});
}
function init() {
Q.Promise.all(this._list.map(getUserInfo))
.then(filterUsers.bind(this))
.then(function (matchedUsers) {
// matchedUsers is an array of all the users you want.
// use it as needed
});
}