I got confused while running my code. I am trying to make an API route for searching books and when I apply POST method it works and does what I want to achieve while there is nothing in body but when I apply GET method it shows following error:
CastError: Cast to ObjectId failed for value "search" (type string) at path "_id" for model "bookmodel"
at model.Query.exec (E:\FullStacks\BookStore\node_modules\mongoose\lib\query.js:4803:21)
at model.Query.Query.then (E:\FullStacks\BookStore\node_modules\mongoose\lib\query.js:4902:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
messageFormat: undefined,
stringValue: '"search"',
kind: 'ObjectId',
value: 'search',
path: '_id',
reason: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer
what could be the reason behind it? route:
router.get("/search", bookcontoller.searchBook)
async searchBook(req, res) {
try {
const { query } = req.query;
console.log(query);
if (!query) {
return res.status(400).json({ success: false, msg: "query not found" });
}
const searchResult = await bookModel.find({$or:[{name:{$regex:".*" query ".*"}}, {genre:{$regex:".*" query ".*"}}]})
if(searchResult.length == 0){
return res.json({success:false, msg:"nothing found of that query"})
}
return res.status(200).json({success:true, msg:"search has been successful", searchResult})
} catch (error) {
return res.status(400).json(error);
}
}
url:
localhost:8000/book/search?query=hi
CodePudding user response:
You very likely also have a route looking like this:
router.get('/:id', ...)
And the handler of that route uses req.params.id
to perform a query on bookModel
to find the book with that id.
Then, you declared the route you're showing:
router.get('/search', …)
Express does not pick the best route handler that matches, but the first. And a request for /search
will match the route for /:id
just fine. So you're performing a query against bookModel
using the word "search" (now in req.params.id
) as _id
, which fails because that's not a valid ObjectId
.
The solution is to always declare more specific route handlers first:
router.get('/search', …)
router.get('/:id', …)