#100DaysOfMERN - Day 31
β 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 subsribe to my newsletter. Until next time π
β Previous Posts
- 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 packages - Day 3: Create a React app without create-react-app, Webpack, Babel
- Day 4:
npx
and cowsay - Day 5:
npm
vs.npx
,npm audit
, semantic versioning and update rules - Day 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.js - Day 9: Network requests with
XMLHttpRequest
and callbacks - Day 10: Promises
- Day 11: Network requests with
XMLHttpRequest
and Promises - Day 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
Software Engineer
Interesting, I might do something similar!
If you don't mind, what resources are you using to learn?
Apart from The Net Ninja and Traversy Media, I can't really cite any resources that I'd use regularly.
Specifically for the MERN stack though, I can recommend the Full Stack Course from Helsinki University. But the learning curve is steep to say the least, I often get stuck and have to do additional research.
I've also bought the most recent Udemy MERN course from Brad Traversy, but realised I couldn't keep up with the pace - which was the initial motivation for this blog. I think I'm almost ready now to go back to it, though.
And I'd love to read about how others tackle this challenge!
Avid learner | Frontend Developer , open source enthusiast
Your posts are so insightful. π It's like a complete roadmap. You have come a long way. I wonder where it will lead at the end of 100 days.
Also, Can you share a few resources you are following?
Thank you! When I started out, 100 days seemed not enough to learn the whole MERN stack, but it's going surprisingly smooth.
My resources-of-choice whenever I want to learn something completely new are these two YT channels, they have almost everything covered:
Other than that, I mostly use the official documentations, or just throw a specific problem into my search engine.
Comments (5)