Search code examples
jsonnode.jsrestexpresslodash

Multiple Query Values in Get Request to JSON based Express Api


I have followed this tutorial https://jonathanmh.com/building-a-simple-searchable-api-with-express-backend/. However I can't seem to get it to work even when I copy the source code. I'm not sure if I have done something wrong that I have missed. Basically when using 2 query parameters I get all the records returned in the response. It works with one fine. The api route is

app.get('/api/stores', function(req, res){
  var response = [];
  console.log(req.query)

  // this would usually adjust your database query
   if(typeof req.query.nsfw != 'undefined'){
     stores.filter(function(store){
      if(store.nsfw.toString() == req.query.nsfw){
       response.push(store);
      }
     });
   } 

 // this would usually adjust your database query
  if(typeof req.query.location != 'undefined'){
    stores.filter(function(store){
      if(store.location === req.query.location){
       response.push(store);
     }
    });
   }

  // de-duplication:
    response = _.uniqBy(response, 'id');

  // in case no filtering has been applied, respond with all stores
    if(Object.keys(req.query).length === 0){
     response = stores;
   }

   res.json(response);
   });

The JSON file is

    const stores = [
  {
    id: 1,
    name: 'Hollows End Grim Potions',
    imageURL: 'https://images.unsplash.com/photo-1465433360938-e02f97448763?    auto=format&fit=crop&w=1267&q=60&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D',
    location: 'Hollows End',
    nsfw: true
  },
  {
    id: 2,
    name: 'Lembas Food Truck',
    imageURL:      'https://images.unsplash.com/reserve/DHHQbqc0RrWVf0uDNe5E_The%20Litte%20Cafe.jpg?auto=format&fit=crop&w=1489&q=60&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D',
location: 'Lothlorien',
nsfw: false
  },
  {
    id: 3,
    name: 'Galadriels Mirror of Brutal Truth',
    imageURL: 'https://images.unsplash.com/photo-1497519098947-a305f214d3bc?auto=format&fit=crop&w=1350&q=60&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D',
    location: 'Lothlorien',
    nsfw: true
  },
  {
    id: 4,
    name: 'Jabbas Light Sabers',
     imageURL: 'https://images.unsplash.com/photo-1481241857164-e8483bce922d?auto=format&fit=crop&w=1353&q=60&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D',
    location: 'Mos Eisley',
    nsfw: true
   }
 ];

module.exports = stores;

So to reiterate my question- why if I place http://localhost:3000/api/stores?location=Lothlorien&nsfw=true do I not only get id:3? Right now I get all records returned.

EDIT:

I just tried it with http://localhost:3000/api/stores?location=Lothlorien&nsfw=false and I strangely get two records ID:2 & ID:3 when I should only be getting ID:2


Solution

  • You're filtering on the conditions separately and pushing the results of each onto your response array instead of using && to filter both conditions together.

    For example when filtering on location=Lothlorien OR nsfw=true, you get 2 results for the location and 3 for the nsfw which uniquely includes 4 (all of them). However, if it had to meet both criteria together, you'd expect to get 1 result - only 1 location named Lothlorien that has nsfw of false.

    Here's an example using &&:

    const { location=null, nsfw=null } = req.query;
    if (location && nsfw) {
      stores.filter((store) => {
        if(store.nsfw.toString() === nsfw && store.location === location){
          response.push(store);
        }
      });
    }