Node.js beginner struggling with arrays, promises and Async

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Node.js beginner struggling with arrays, promises and Async



A node.js (and coding in general) beginner here, struggling with the async nature of node. I'm trying to write some code that will look up the members of certain AD groups and add the member names to an array, as per the "getMembers" function below. I'm only interested in computer objects, which is why I only have ad.find returning "other" objects.



Once that is complete, I want the "processAssets" function to do something with the array - for the purpose of testing, just ouptutting to the console.log. The problem is that "processAssets" is running before "getMembers" has populated the array. What am I doing wrong? I realise the answer may begin with "several things"...!


const ActiveDirectory = require('activedirectory');
var ad = new ActiveDirectory(config);
var query = 'memberOf=cn=';
var cNames = [
'group1',
'group2',
'group3'
];
var baseOu = ',ou=Groups,dc=example,dc=com';
function run(cNames)
Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())


async function getMembers(cName)
await ad.find(query + cName + baseOu, async function(err, results)
if ((err) );


function processAssets()
console.log("Contents of assetArray (" + assetArray.length + " assets):");
assetArray.forEach(function(item)
console.log(item);
);



thanks in advance.





Are you sure that .find returns a Promise? It looks to be callback-based.
– CertainPerformance
Aug 6 at 0:26


.find


Promise





I should have mentioned that I'm using the activedirectory package, not ad directly. I've updated the question to make that clearer.
– Adam
Aug 6 at 0:36





So, are you sure that .find returns a Promise?
– CertainPerformance
Aug 6 at 0:37


.find


Promise





No I'm not sure - as I said I'm a beginner, and despite researching this website and others I feel I've missed something fundamental.
– Adam
Aug 6 at 0:40




1 Answer
1



You have some things mixed up.



The main problem causing your immediate issue is this line:


Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())



You need to pass a function to then() which will be called when the promise resolves. You are not doing that, you are passing it the result of calling processAssets(), which has the effect of calling processAssets() immediately. Typically you would us something like:


then()


processAssets()


processAssets()


Promise.all(cNames.map(cName => getMembers(cName))).then(() => processAssets())
/* ^^ pass a function */



Additionally you are await things for no purpose. There's no reason to await here:


await


await ad.find(query + cName + baseOu, async function(err, results) {



ad.find doesn't return a promise. In general functions that take callbacks don't return promises (maybe there are some exceptions, but I can't think of any). If you want to have a promise to use in run()'s Promise.all you need to wrap the find function in a promise and return it. Something like:


ad.find


run()


Promise.all


find


function getMembers(cName)
return new Promise((resolve, reject) =>
ad.find(query + cName + baseOu, function(err, results)
if (err) return reject(err)
// I'm making some assumptions about results. But hopefully this gives
// a good enough idea
let data = results.other.map(other => other.cn)
resolve(data)
);
);



Now getMembers returns a promise that resolves to the result of ad.find and you can use it in `Promise.all.


getMembers


ad.find





thanks for the explanation Mark.
– Adam
Aug 7 at 4:20






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS