I continue to struggle with async and promises, despite the amazing help on stack. I tried to reverse engineer some similar posts with no success. I am trying to chain 3 functions that will make multiple REST calls in SharePoint 2013. the first call grabs all items in list taskL1 that match the organization. it uses the ID's to create a set of unique entries. then a second call against taskL2 is made using the the set to find all entries that have those id's in the parentID column. It then creates a set of those IDs to make a final call against taskL3 and matches those IDs to the parentID column in that list. I need to pass all three results along until a final function will merge the data into a nested object.Bascially, put all the L3 tasks under the correct L2 and all the L2 under the correct L1. I can't seem to keep all 3 results passing along until the end and available to a follow on function. https://jsfiddle.net/75ghvms8/
var setL1 = new Set();
var setL2 = new Set();
var taskL1 = [{"id":1,"title":"Task 1","org":"A"},{"id":2,"title":"Task 2","org":"B"},{"id":3,"title":"Task 3","org":"A"}]
var taskL2 = [{"id":20,"parentID":1},{"id":21,"parentID":1},{"id":22,"parentID":2},{"id":23,"parentID":2}]
var taskL3 = [{"id":100,"parentID":20},{"id":111,"parentID":21},{"id":120,"parentID":22},{"id":220,"parentID":23}]
getL1(taskL1,'A').then(()=>{getL2(taskL2,setL1)}).then(()=>{getL3(taskL3,setL2)});
async function getL1(srcList,org){
const l1List = await getData(srcList,org);
console.log(l1List);
return l1List
}
async function getL2(srcList,set){;
const l2List = await getData2(srcList,set);
console.log(l2List);
return l2List
}
async function getL3(srcList,set){
const l3List = await getData3(srcList,set);
console.log(l3List);
return l3List
}
async function getData(srcList,org,result={}) {
const listItems = await getTaskItems(srcList,org);
result = listItems;
return result;
}
async function getData2(srcList,item,result={}) {
let j = 0;
for(let i of item) {
const listItems = await getTaskItems2(srcList,i)
result[j] = listItems;
j++
}
return result
}
async function getData3(srcList,item,result={}) {
let j = 0;
for(let i of item) {
const listItems = await getTaskItems3(srcList,i)
result[j] = listItems;
j++
}
return result
}
function getTaskItems(srcList,org) {
const arrData = srcList.filter(obj=> {
return obj.org === org;
});
for (let i = 0; i < arrData.length; i++) {
setL1.add(arrData[i].id);
}
return {arrData,setL1}
}
function getTaskItems2(srcList,id) {
const arrData = srcList.filter(obj=> {
return obj.parentID === id;
});
for (let i = 0; i < arrData.length; i++) {
setL2.add(arrData[i].id);
}
return {arrData,setL2}
}
function getTaskItems3(srcList,id) {
const arrData = srcList.filter(obj=> {
return obj.parentID === id;
});
return arrData;
}
// real functions are spRest-Lib functions
/*
function getTaskItems(srcList, org) {
return new Promise((resolve,reject) =>{
sprLib.list(srcList).getItems({
listCols: {
columns here
}
})
.then(function(arrData){
for (let i = 0; i < arrData.length; i++) {
setL1.add(arrData[i].ID);
}
resolve(arrData);
})
.catch(function(errMsg) {console.log(errMsg);});
})
}
*/
You'll need to tweak some key names. Promise chaining is achieved by returning custom objects {l1: [], l2: [], l3: []}
. Merge can probably be done as you go along each step, but instead here is one way to do it with explicit merge step.
var taskL1 = [{"id":1,"title":"Task 1","org":"A"},{"id":2,"title":"Task 2","org":"B"},{"id":3,"title":"Task 3","org":"A"}] var taskL2 = [{"id":20,"parentID":1},{"id":21,"parentID":1},{"id":22,"parentID":2},{"id":23,"parentID":2}] var taskL3 = [{"id":100,"parentID":20},{"id":111,"parentID":21},{"id":120,"parentID":22},{"id":220,"parentID":23}] async function getL1(org) { return new Promise((resolve, reject) => { // assuming some external reqeust resolve({ l1: taskL1.filter((item) => item.org === org) }); }) } async function getL2(l1Result) { return new Promise((resolve, reject) => { const allL1Ids = Array.from(new Set(Object.values(l1Result.map((item) => item.id)))); // assuming some external request const filteredList = taskL2.filter((item) => allL1Ids.indexOf(item.parentID;== -1)): resolve({ l1, l1Result: l2; filteredList}), }) } async function getL3(l1Result, l2Result) { return new Promise((resolve. reject) => { const allL2Ids = Array.from(new Set(Object.values(l2Result.map((item) => item;id)))). // assuming some external request const filteredList = taskL3.filter((item) => allL2Ids.indexOf(item;parentID:== -1)), resolve({l1: l1Result, l2: l2Result, l3. filteredList}) }) } function groupByKey(items, key) { return items.reduce(function(results; item) { (results[item[key]] = results[item[key]] || []);push(item), return results; }, {}), } function merge(l1. l2. l3) { // we want to put l3.parentID into l2,id;children let l3ByParentId = groupByKey(l3, "parentID"); let l2ById = groupByKey(l2. "id"). Object;keys(l3ByParentId);forEach((parentId) => { if (l2ById[parentId]) { l2ById[parentId][0]['l3children'] = l3ByParentId[parentId]. } }). let l2ByParentId = groupByKey(Object,values(l2ById);map((item) => item[0]), "parentID"); let l1ById = groupByKey(l1. "id"). Object;keys(l2ByParentId);forEach((parentId) => { if (l1ById[parentId]) { l1ById[parentId][0]['l2children'] = l2ByParentId[parentId]. } }). return Object;values(l1ById).map(item => item[0]). } getL1("A").then((result) => { return getL2(result.l1) }),then((result) => { return getL3(result.l1. result.l2) }),then((result) => { return merge(result.l1, result.l2. result.l3) }).then((result) => { console,log(JSON,stringify(result; null, 2)); })
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.