search

Home  >  Q&A  >  body text

Regular expression filter for MERN stack search boxes and checkboxes

I'm trying to learn how the MERN stack works together by learning by doing, and I'm following these tutorials for bezcoder: Node.js/Express/MongoDb (Github Entire Code) and Reactjs (Github Entire Code)

Sample data from server

[
  {
    "id": "5f9bdace778082303c859248",
    "title": "How to cook noodles",
    "description": "This is a tutorial about how to cook noodles in under 10 minutes.",
    "published": false
  },
  {
    "id": "5f9bdae3778082303c859249",
    "title": "How to bake a chocolate cake",
    "description": "This is a tutorial about how to bake chocolate cake using cocoa powder.",
    "published": true
  }
]

status quo Currently, the frontend of the app has a search bar where I can search and filter the data by the "title" of the tutorial (e.g. "Noodles" to get the first one). I found that this is done with the following code snippet:

  1. tutorial.controller.js
exports.findAll = (req, res) => {
  const title = req.query.title;
  var condition = title ? { title: { $regex: new RegExp(title), $options: "i" } } : {};

  Tutorial.find(condition)
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving tutorials."
      });
    });
};
  1. services/tutorial.service.js (in Reactjs)
import http from "../http-common";

class TutorialDataService {

...
  
  findByTitle(title) {
    return http.get(`/tutorials?title=${title}`);
  }
}

export default new TutorialDataService();

What I want to know is,, how do I change these codes so that I can filter by words in the search box "title" and "description" and the published:true pass checkbox.

If the front end looks like this:

My attempt

  1. tutorial.controller.js
exports.findAll = (req, res) => {
  const title = req.query.title || "";
  const description = req.query.description || "";
  const published = req.query.published;

  Tutorial.find(
    {
    $or: [
        {title: { $regex: new RegExp(title), $options: "i"}}, {description: { $regex: new RegExp(description), $options: "i"}}
    ],
    $and: [
        .... and here if checked, then only show published, else show all ....
    ]

}

  )
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving tutorials."
      });
    });
};
  1. services/tutorial.service.js (in Reactjs)
import http from "../http-common";

class TutorialDataService {

...
  
  findByTitle(title, description, published) {
    return http.get(`/tutorials?title=${title}`, `/tutorials?description=${description}`, `/tutorials?published=${published}`);
  }
}

export default new TutorialDataService();

I'm not sure if this is the correct usage of findByTitle and how to implement the OR and AND functions correctly.

P粉302160436P粉302160436263 days ago612

reply all(1)I'll reply

  • P粉792673958

    P粉7926739582024-04-07 00:09:45

    The code in your { has an error in the tutorial find query. $or Each query requires a separate { }. Use it like below. It will work. Used to search within title, description, and published checkboxes.

    Tutorial.find:({
    $or: [
            {title: { $regex: new RegExp(title), $options: "i"},
            {description: { $regex: new RegExp(description), $options: "i"}
        ],
    published:true
    })

    reply
    0
  • Cancelreply