I am trying to query my database several times and construct an object which stores every response from my database in a field. Here is my code:
router.post('/search', (req, res) => {
var collection = db.get().collection('styles')
var data = [];
collection.distinct('make.name', (err, docs) => {
data.push({'make': docs });
});
collection.distinct('model', (function (err, docs) {
data.push({'model': docs });
}))
res.send(data);
});
Since NodeJS/Express is asynchronous, this isn't working as I would like. How can I reconstruct this endpoint to make several database calls (from the same collection) and return an object containing it?
You can do it with Promises
Also you can use destructuring in callback functions like that:
UPD: If you have a bunch of collection to request you can create an array of collections name, map it to promise requests and handle with Promise.all, for example
There's more than one way to do it:
Nested callbacks
Without promises you could nest the callbacks:
This would be the easiest way, but note that it is not efficient if those two requests could be done in parallel.
The
async
moduleYou can use the
async
module:See: https://caolan.github.io/async/docs.html#parallel
But this may still not be the most convenient method.
ES2017
async
/await
The most flexible way of doing that if you have 30 calls to make would be to:
Promise.all()
for anything that can be done in parallelWith async/await your code could look like this:
Or:
A big advantage of
async
/await
is the error handling:You can only use it inside of a function created with the
async
keyword. For more info, see:For support in browsers, see:
For support in Node, see:
In places where you don't have native support for
async
andawait
you can use Babel:or with a slightly different syntax a generator based approach like in
co
or Bluebird coroutines:See those answers for more info: