I don't know why, but after an reinstall from ghost it works.
I do what @The-Worms posted. And, that works 🤸
@The-Worms Thank you! 🍻
Hello,
I am trying to use an async.each during an asyc.waterfall in a NodeBB plugin, however the order of execution is not what I expect.
Code:
async.waterfall([
function(next) {
Groups.getGroupsFromSet('groups:createtime', 0, 0, -1, next);
},
function(groups, next) {
// log(`groups: ${groups}`)
// log(`groups: ${groups[0].name}`)
next(err, groups)
},
function(groups, next) {
async.each(groups, function(element, eachCallback) {
if (!element.name.match('privileges')) {
Groups.ownership.isOwner(uid, element.name, function(err, isOwnerBool) {
if (isOwnerBool) {
renderData.groups.push(element)
log(`element.name: ${element.name}`)
}
})
}
eachCallback(err)
},
function(err) {
if (err) {
log(`ERROR in async.each! ${err}`);
} else {
log('No error happened in any steps, next()!');
}
next(err)
})
},
function(next) {
log('I got called!')
log(`renderData.groups: ${renderData.groups}`)
next(err)
}
],
function(err) {
if (err) {
log(`ERROR! ${err}`);
} else {
log('No error happened in any steps, operation done!');
}
});
Actual output:
No error happened in any steps, next()!
I got called!
renderData.groups:
No error happened in any steps, operation done!
element.name: My Group A
element.name: My Group B
Expected output:
element.name: My Group A
element.name: My Group B
No error happened in any steps, next()!
I got called!
renderData.groups: [object Object],[object Object]
No error happened in any steps, operation done!
Any help is appreciated, thank you
Edit: Adjusted expected output, sorry for the confusion.
You need to call eachCallback
within the callback you pass to Groups.ownership.isOwner
. In the case you have a privilege group, you can just exit early like so:
// not exactly what you want, just an example
if (condition) {
callback();
return;
}
// then do other stuff
Do you mean this?
async.waterfall([
function(next) {
Groups.getGroupsFromSet('groups:createtime', 0, 0, -1, next);
},
function(groups, next) {
// log(`groups: ${groups}`)
// log(`groups: ${groups[0].name}`)
next(err, groups)
},
function(groups, next) {
async.each(groups, function(element, eachCallback) {
if (!element.name.match('privileges')) {
Groups.ownership.isOwner(uid, element.name, function(err, isOwnerBool) {
if (isOwnerBool) {
renderData.groups.push(element)
log(`element.name: ${element.name}`)
}
eachCallback(err)
})
}
},
function(err) {
if (err) {
log(`ERROR in async.each! ${err}`);
} else {
log('No error happened in any steps, next()!');
}
next(err)
})
},
function(next) {
log('I got called!')
log(`renderData.groups: ${renderData.groups}`)
next(err)
}
],
function(err) {
if (err) {
log(`ERROR! ${err}`);
} else {
log('No error happened in any steps, operation done!');
}
});
This leads to the following output:
element.name: My Group A
element.name: My Group B
For context, I am trying to get a list of all groups, of which the current user is the owner.Therefore I also do not want to exit the async.each on the first privilege group, but find them all and add them to the renderData.groups array.
@navid-sassan you need to call eachCallback no matter what, otherwise it will hang.
async.each(groups, function(element, eachCallback) {
if (element.name.match('privileges')) {
eachCallback();
return; // only exits this callback function, skips the ownership check
}
Groups.ownership.isOwner(uid, element.name, function(err, isOwnerBool) {
if (isOwnerBool) {
renderData.groups.push(element)
log(`element.name: ${element.name}`)
}
eachCallback(err)
}),
}
Just FYI, pretty sure you can use async.filter
for this.
Thank you very much! The code worked, and I will look into async.filter, it looks promising, thanks for the hint