✏ How to implement a live search function
Yesterday's plan was to code a recipe database, and in fact I've already built 80% of it, but I've decided against blogging about the whole process. Instead I'll pick certain parts and describe those in detail - like a live search function.
The goal: When I fill out the form to add a new recipe to the database, and start typing into the input field to add an ingredient for this recipe, I'm shown a list of ingredients that are already in the database.
The data structure
I have an Ingredient collection in my database, based on this Schema:
const IngredientSchema = new Schema({
name: {
type:String,
required:true,
unique:true
}
}, { timestamps: true });
const Ingredient = mongoose.model('ingredient', IngredientSchema);
module.exports = Ingredient;
The Backend
The server has an API endpoint /api/ingredients
, which returns a list of all ingredients in the database, using the .find
method on the Model:
app.get('/api/ingredients/', (req, res) => {
Ingredient.find()
.then(data => res.json(data))
.catch(err => console.log(err))
})
I'm going to modify this now, to check first if there's a query string attached to the request. For example, if I make a request to /api/ingredients?search=tom
, the search string would be available on the req.query
object:
req.query // {search: "tom"}
In that case, the .find
method should look for possible matches, and only return those. Conveniently, Mongoose allows passing a RegExpression:
app.get('/api/ingredients/', (req, res) => {
if (req.query.search) {
const regex = new RegExp(req.query.search, 'g');
Ingredient.find({ name: regex})
.then(data => res.json(data))
.catch(err => console.log(err))
} else {
Ingredient.find()
.then(data => res.json(data))
.catch(err => console.log(err))
}
})
The Frontend
When I type more than two characters into the ingredient field, the onChange
handler of the input will trigger an axios
GET request to the api/ingredients
endpoint, with a query string attached:
function getIngredients(str){
axios.get(`/api/ingredients?search=${str}`)
.then(res => {
const ingredients = res.data.map(e => e.name);
setIngredients(ingredients);
})
.catch(err => console.log(err))
}
The response will be an array with all matches, which can then be stored in state, ready for React to display. And indeed - typing "tom" into my input field, I'm shown a match: "Tomato" is already in the database 🍅
✏ Recap
I've learned
- how to implement a live search function using
axios
andmongoose
✏ Thanks for reading!
I do my best to thoroughly research the things I learn, but if you find any errors or have additions, please leave a comment below, or @ me on Twitter. If you liked this post, I invite you to subscribe to my newsletter. Until next time 👋
Day 1: Introduction, Node.js, Node.js in the terminal
Day 2:
npm
, node_modules,package.json
andpackage-lock.json
, local vs global installation of packagesDay 3: Create a React app without create-react-app, Webpack, Babel
Day 4:
npx
and cowsayDay 5:
npm
vs.npx
,npm audit
, semantic versioning and update rulesDay 6: Call stack, event loop, JavaScript engine, JavaScript runtime
Day 7: Call stack and event loop in Node.js,
setImmediate()
Day 8:
setImmediate()
,process.nextTick()
, event loop phases in Node.jsDay 9: Network requests with
XMLHttpRequest
and callbacksDay 10: Promises
Day 11: Network requests with
XMLHttpRequest
and PromisesDay 12: React Quiz App part 1
Day 13: React Hangman
Day 14: FullStackOpen course 1: details of GET and POST requests, request headers
Day 15: React Hangman: Trigger fetch with click event callback vs useEffect
Day 16: REST API and CRUD
Day 17: Boring Book App part 1: React Frontend, Express Backend, GET requests, CORS
Day 18: Boring Book App part 2: POST request, File System API
Day 19: Boring Book App part 3: Request Parameters, DELETE request
Day 20: Boring Book App part 4: PUT request
Day 21: Express JS vs Vanilla JS part 1: Server setup, routes
Day 22: Express JS vs Vanilla JS part 2: Serve static files with Vanilla Server
Day 23: Express JS vs Vanilla JS part 3: Serve static files with Express Server, Middleware
Day 24: Express JS: express.Router, Postman
Day 25: Express JS: express-handlebars
Day 26: MongoDB: Installation, noSQL database structure, Mongo Shell commands
Day 27: MongoDB: Project setup, JSON vs BSON, connecting to database, inserting a record
Day 28: MongoDB: read and modify data with CRUD operations
Day 29: MongoDB with Mongoose: Connecting to the database, Models, Schemas, Saving to the database
Day 30: 100DaysOfMERN - App: Backend, Frontend