'Search an item with mongoose
I want to search for a specific item from the database(mongodb) using mongoose ODM and display the item in my view. This is what I have found from the internet but its not working. Here is my controller:
exports.getSearch = (req, res, next) => {
const { name } = req.query;
Product.find({title: { $regex: name, $options: "i" }})
.then(title => {
res.render('shop/product-list', {
prods: title ,
pageTitle: 'All Products',
path: '/products'
});
})
.catch(err => {
console.log(err);
});
}
When I run my server I get this error after trying to search:
CastError: Cast to ObjectId failed for value "search" (type string) at path "_id" for model "Product"
Here is my search form:
<form action="/products" method="POST">
<input type="text" placeholder="search product" name="name">
<button type="submit">Search</button>
</form>
Sample of the fields in my mongodb:
_id: 628398cb487a2cf1538c4087
title: "Dell E7240"
price: 28600
description: "Dell Latitude E7240
Core i5 4th gen
12'
4GB RAM
120GB SSD"
imageUrl: "images/2022-05-17T12:44:58.743Z-e7250.jpg"
userId: 627540c6672b6ab4007a3856
__v: 0
My product Schema:
const productSchema = new Schema({
title: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
description: {
type: String,
required: true
},
imageUrl: {
type: String,
required: true
},
userId: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
});
Solution 1:[1]
use this
exports.getSearch = (req, res, next) => {
const { title } = req.query;
Product.find({title: { $regex: title, $options: "i" }})
.then(prodName => {
res.render('shop/product-list', {
prods: prodName ,
pageTitle: 'All Products',
path: '/products'
});
})
.catch(err => {
console.log(err);
});
}
Solution 2:[2]
Because I was doing a post request and passing form data(title) to be filtered; I ought to have used req.body. This controller worked:
exports.getSearch = (req, res, next) => {
const title = req.body.title;
Product.find({ title: { $regex: title, $options: "i" } })
.then(title => {
res.render('shop/index', {
prods: title ,
pageTitle: 'All Products',
path: '/products'
});
})
.catch(err => {
console.log(err);
});
}
Solution 3:[3]
The first one is regular URL while the second use URL namespaces.
URL namespaces allow you to uniquely reverse named URL patterns even if different applications use the same URL names. It’s a good practice.
For example you can have a url like that : {% url 'blog:index' %} and {% url 'shopping:index' %}
See the documentation
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Gaëtan GR |
