I am working with Node Js and Express, I make the queries to MongoDB through Mongoose. I am having trouble with a get request that can receive 3 optional parameters.
For example:
http://localhost:3000/transactions/?dateFrom=2019-01-01&dateTo=2020-07-07&account=1234
The query in mongoDB would be like this in the case of receiving all the parameters, it works fine:
const transaction = await Transfer.find ({date: {$ gte: dateFrom, $ lte: dateTo}, accountFrom: accountID} {date: {$ gte: dateFrom, $ lte: dateTo}, accountFrom: accountID});
My problem is that I can receive 1, 2, or 3 parameters and the query would change. I have a way to tell mongo not to take a parameter into account if it is undefined?
My complete code (works but it's a horror!). If there were 10 optional parameters it would be impossible to do this:
router.get('/', async (req, res) => {
let dateFrom = req.query.dateFrom;
let dateTo = req.query.dateTo;
let accountID = req.query.accountID;
let query;
if (typeof dateFrom != 'undefined' && typeof dateTo != 'undefined' && typeof accountID != 'undefined') query = { date: { $gte: dateFrom, $lte: dateTo }, accountFrom: accountID };
if (typeof dateFrom != 'undefined' && typeof dateTo != 'undefined' && typeof accountID == 'undefined') query = { date: { $gte: dateFrom, $lte: dateTo } };
if (typeof dateFrom != 'undefined' && typeof dateTo == 'undefined' && typeof accountID != 'undefined') query = { date: { $gte: dateFrom }, accountFrom: accountID };
if (typeof dateFrom == 'undefined' && typeof dateTo != 'undefined' && typeof accountID != 'undefined') query = { date: { $lte: dateTo }, accountFrom: accountID };
if (typeof dateFrom != 'undefined' && typeof dateTo == 'undefined' && typeof accountID == 'undefined') query = { date: { $gte: dateFrom }};
if (typeof dateFrom == 'undefined' && typeof dateTo != 'undefined' && typeof accountID == 'undefined') query = { date: { $lte: dateTo }};
if (typeof dateFrom == 'undefined' && typeof dateTo == 'undefined' && typeof accountID != 'undefined') query = { accountFrom: accountID };
const transaction = await Transfer.find({ date: { $gte: dateFrom, $lte: dateTo }, accountFrom: accountID }{ date: { $gte: dateFrom, $lte: dateTo }, accountFrom: accountID });
if (!transaction) return res.status(404).send('The transaction with the given ID was not found.');
res.send(transaction);
});
The explanation was a bit long but I wanted to give all the context.
Thanks so much for any help!
There's no work around that avoids using custom logic, but we can make it a little more read-able and scaleable by utilizing Mongo's built in boolean operators like $and. By doing so we can avoid checking every single permutation and just construct the conditions as we go.
router.get('/', async (req, res) => {
let dateFrom = req.query.dateFrom;
let dateTo = req.query.dateTo;
let accountID = req.query.accountID;
let conditions = [];
if (!!dateFrom) {
conditions.push({date: {$gte: dateFrom}});
}
if (!!dateTo) {
conditions.push({date: {$lte: dateFrom}});
}
if (!!accountID) {
conditions.push({accountFrom: accountID});
}
let final_condition = conditions.length ? {$and: conditions} : {};
const transaction = await Transfer.find(final_condition);
if (!transaction) return res.status(404).send('The transaction with the given ID was not found.');
res.send(transaction);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With