You are not setting up the functions properly. The expected argument are function() wrappers with a callback argument which gets passed to when the contained async function completes.
You also really just want async.map instead of what you are doing, because it's output is an array of the results from the looped calls. So no need to push results into an external variable:
app.get('/api/wherecritique/reviews/search/:author', function(req,res) {
Critique.find({author: req.params.author}, function(err,cris) {
async.map(
cris.map( c => c.reviewID ),
function(id, callback) {
Review.findOne({ id: id }, callback);
},
function(err,results) {
if (err) throw err; // or something with err
console.log(results);
res.json(results);
}
);
});
});
But in all honesty you should really be using Promises here rather than import an external library
app.get('/api/wherecritique/reviews/search/:author', function(req,res) {
Critique.find({author: req.params.author}, function(err,cris) {
Promise.all(
cris.map( c => Review.findOne({ id: c.reviewID }) )
).then( results => {
console.log(results);
res.json(results);
}).catch( e => console.error(e) );
});
});
Or in a more modern way with async/await:
app.get('/api/wherecritique/reviews/search/:author', async (req,res) => {
try {
let cris = await Critique.find({author: req.params.author});
let results = Promise.all(
cris.map( c => Review.findOne({ id: c.reviewID }) )
);
console.log(results);
res.json(results);
} catch(e) {
console.error(e);
}
});
But in actual reality, this has nothing to do with JavaScript at all, and you really should be using MongoDB features.
Either with $lookup where supported:
app.get('/api/wherecritique/reviews/search/:author', async (req,res) => {
try {
let results = await Critique.aggregate([
{ $match: { author: req.params.author } },
{ $lookup: {
from: Review.collection.name,
localField: 'reviewID',
foreignField: 'id'
as: 'reviews'
}},
{ $unwind: '$reviews' }
]);
results = results.map( r => r.reviews );
console.log(results);
res.json(results);
} catch(e) {
console.error(e);
}
});
Or if you don't have that, then simply passing all id values to $in:
app.get('/api/wherecritique/reviews/search/:author', async (req,res) => {
try {
let cris = await Critique.find({ author: req.params.author });
let results = await Review.find({ id: { $in: cris.map( c => c.reviewID ) } });
console.log(results);
res.json(results);
} catch(e) {
console.error(e);
}
});
Which means either "one" or "two" actual calls to the database depending on your MongoDB version. No need to loop async calls at all.
Finally, it's really not necessary as explained by all the above, but the correct usage of async.parallel would be:
app.get('/api/wherecritique/reviews/search/:author', (req,res) => {
Critique.find({author: req.params.author}, (err,cris) => {
var tasks = cris.map( c => (callback) =>
Review.findOne({ id: c.reviewID }, callback);
);
async.parallel(
tasks,
(err,results) => {
if (err) throw err; // or something
console.log(results);
res.json(results);
}
)
});
});