I am trying to sort my data by price, descending. In the following controller, I am able to filter for operations like greater than less than, less than or equal to... However, I create an if statement to check if a query has sort (localhost:3000/api/v1/tours?sort=price) and it does, so then in the block code, I am trying to sort. What ends up happening with the code below is the error
{
"status": "failure",
"results": "Parameter \"filter\" to find() must be an object, got price"
}
I am taking a course where students are using Mongoose 5 and I am using 6. Whenever I use other code like--for the if statement--
if (queryString.sort) {
queryString = queryString.sort(req.query.sort);
}
then I get errors like
{
"status": "failure",
"results": "queryString.sort is not a function"
}
in my postman application. It almost seems as if the code in my if statement is ignored or tramples into an error.
exports.getAllTours = async (req, res) => {
try {
let queryString = JSON.stringify(req.query);
queryString = queryString.replace(
/\b(gte|gt|lte|lt)\b/g,
(match) => `$${match}`
);
let = queryString = JSON.parse(queryString);
if (queryString.sort) {
queryString = queryString.sort;
}
const tours = await Tour.find(queryString);
res
.status(200)
.json({ status: 'ok', results: tours.length, data: { tours } });
//TODO: Will fine tune error despite somewhat working
} catch (err) {
// eslint-disable-next-line no-console
console.log(err);
res.status(404).json({ status: 'failure', results: err.message });
}
};
Here are some questions I am having:
- How do I use Mongoose's sort function appropriately in this scenario?
CodePudding user response:
If you want to filter and sort at same time then you can try
let queryString = req.query;
let API;
if(queryString.filter){
API = Tour.find(queryString.filter);
}
if(queryString.sort){
API = API.sort({[queryString.sort]: -1});
}
let tours = await API.exec();
res
.status(200)
.json({ status: 'ok', results: tours.length, data: { tours } });```
CodePudding user response:
I realized that I had to use JSON.parse inside the find method.
exports.getAllTours = async (req, res) => {
try {
let queryString = JSON.stringify(req.query);
queryString = queryString.replace(
/\b(gte|gt|lte|lt)\b/g,
(match) => `$${match}`
);
let query = Tour.find(JSON.parse(queryString));
if (req.query.sort) {
query = query.sort(req.query.sort);
}
const tours = await query;
res
.status(200)
.json({ status: 'ok', results: tours.length, data: { tours } });
//TODO: Will fine tune error despite somewhat working
} catch (err) {
// eslint-disable-next-line no-console
console.log(err);
res.status(404).json({ status: 'failure', results: err.message });
}
};
CodePudding user response:
put the query code inside the if statements to find() all data, then added .sort() method.
If you want to sort it by price and only show data that qualified, you can try this:
let queryString = req.query;
let tours;
if(queryString.sort){
tours = await Tour.find({[queryString.sort]: {$gt: value, $lt: value}}).sort({[queryString.sort]: -1})
}
res
.status(200)
.json({ status: 'ok', results: tours.length, data: { tours } });
more info you can visit MongoDB .sort()