Home > Blockchain >  How to find specific data using tags with mern stack?
How to find specific data using tags with mern stack?

Time:12-15

I have the backend code where I want to find some data using the tags. The tags will be from react frontend. I tried it doing like the first Backend code where I did it like find({tags: { $all: ["english"] } }). I thought just replacing the ["english] array with the params from the frontend do the same thing. But it just doesn't work.

I just want to find a working solution where I can find specific data using the tags from the frontend.

Backend1:

router.get("/", (req, res) => {
  Test.find({ tags: { $all: ["english"] } }).then((items) => res.json(items));
});

Backend2:

const Test = require("../../models/test");

router.get("/:tags", (req, res) => {
  const query = req.params.tags;
  Test.find({ tags: { $all: [query] } }).then((items) => res.json(items));
});

Frontend:

export default function Test() {

  useEffect(() => {
    fetchItems();
  }, []);

  const fetchItems = async () => {
    const tags = ["english", "noun"]
    const res = await fetch(`/api/test/${tags}`);
    const data = await res.json();
    console.log(data)
  };
  return (
    <div>Hi</div>
  );
}

Data:

[
  { "q": "What is english?", "tags": ["english"] },
  { "q": "What is noun?", "tags": ["english", "noun"] },
  { "q": "What is pronoun?", "tags": [ "english", "pronoun"] }
]

Edit: When I send a get request using fetch like this: const res = await fetch(`/api/test/${tags}`);, the request looks like this: http://localhost:5000/api/test/english,noun.

Is this a good way to send request with a comma in the request string?

Edit 2: For the comma issue in the request string, I did it like this. Seems to work the way I expect. Front:

  const fetchItems = async () => {
    const tags = ["english", "noun"]
    const tags_params = tags.map((l)=>'tags=' encodeURIComponent(l)).join('&')
    const res = await fetch(`/api/test/?${tags_params}`);
    const data = await res.json();
  };

Backend:

const Test = require("../../models/test");

router.get("/", (req, res) => {
  Test.find({ tags: { $all: req.query.tags } }).then((q) => res.json(q));
});

CodePudding user response:

You should split the "req.params.tags" to convert it into an array.

I know that you are surrounding the query variable with [ ] like this :

{ tags: { $all: [query] } }

but this won't put elements separately into array, instead it will put whole string into array as one element.

Check the example below :

My route :

router.get('/test-for-nasem/:tags', async(req, res) => {
try {
    const query = req.params.tags;
    const arr = query.split(',');

    res.send({
        'query-length': [query].length,
        'query': [query],
        'query[0]': [query][0],
        '-----------------------': '',
        'arr-length': arr.length,
        arr,
        'arr[0]': arr[0],
    });
}
catch (error) {
    handleError(error, req, res);
}

});

And when I make a request to this route like this http://localhost:3002/test-for-nasem/apple,banana using postman :

As you can see from the API result, query is not your desired array, while arr is.

enter image description here


On the other hand, there are multiple ways to send array parameter with HTTP GET request.

Express exposes the query parameter as an array when it is repeated more than once in the request URL:

app.get('/', function(req, res, next) {
console.log(req.query.tags)
   res.send(200)
}

GET /?tags=apple&tags=banana
// query.tags is ['apple', 'banana']

Same applies for req.body in other methods.

You could use that format with commas and split the parameter in your backend too.

  • Related