Thanks in advance, but could someone explain to me how can I execute a different query for each property of my request? I am trying to create a search sidebar menu, when user changes checkbox values I create an object with these properties:
{ "category": [ "electronics", "clothing", "pets" ], "condition": [ "old", "new" ] }
I want to push a query into an array of functions and then execute them using async.parallel When called i want to push the result of each query inside one array containing the result of all queries.
router.get('', async function(req,res) { var searchResults = []; if(req.query.filters) { const queryObj = JSON.parse(req.query.filters); var searchQueries = []; if(queryObj.category){ searchQueries.push(async function (cb) { return await Rentals.find({/* SOME CONDITION */}).populate('-something').exec(function (err, docs) { if (err) { throw cb(err); } cb(null, docs); }); }) } if(queryObj.condition){ searchQueries.push(async function (cb) { return await Rentals.find({/* SOME CONDITION */}).populate('-something').exec(function (err, docs) { if (err) { throw cb(err); } cb(null, docs); }); }) } async.parallel(searchQueries, function(err, foundRentals) { if (err) { throw err; } searchResults.push(foundRentals[0]); // result of searchQueries[0] searchResults.push(foundRentals[1]); // result of searchQueries[1] searchResults.push(foundRentals[2]); // result of searchQueries[2] }) } res.json(searchResults); });
The problem comes when returning searchResults, I am receiving an empty array from the server however after the response was sent the queries finish and I get the result AFTER response was sent. How can I execute all queries at the same time and wait until all of them finish before sending a response to client?
Advertisement
Answer
Your promise.all
code version would look something like this:
router.get('', async function(req,res) { try{ let searchResults = [], categoryPromises = [], conditionPromises = []; if(req.query.filters) { const queryObj = JSON.parse(req.query.filters); if(queryObj.category && queryObj.category.length > 0){ categoryPromises = queryObj.category.map(singleCategory=>{ return Rentals .find({/* SOME CATEGORY? */}) .populate('-something') .exec(); }); } if(queryObj.condition && queryObj.condition.length > 0){ conditionPromises = queryObj.category.map(singleCondition=>{ return Rentals .find({/* SOME CONDITION */}) .populate('-something') .exec(); }); } searchResults.push(await categoryPromises); searchResults.push(await conditionPromises); } res.json(searchResults); }catch(e){ // catch-all error handling here } });
(instead of .map you could also use a for-loop to push them into a categoryPromises array)