#100DaysOfMERN - Day 31

Subscribe to my newsletter and never miss my upcoming articles

✏ 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 and mongoose

✏ 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 and package-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
Catalin Pit's photo

Interesting, I might do something similar!

If you don't mind, what resources are you using to learn?

jsdisco's photo

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!

Paolo Urciullo's photo

awesome post!

Rutik Wankhade's photo

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?

jsdisco's photo

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:

The Net Ninja

Traversy Media

Other than that, I mostly use the official documentations, or just throw a specific problem into my search engine.