Having trouble deleting the right item from a list (MERN stack)

Hey, so I’m encountering this issue in a few of my CRUD apps and I can’t pinpoint why. I’m able to create a list of items by posting them from a form. MongoDB Atlas is connected and I can GET and POST. However, when I try to DELETE an item, it will always delete the first one in the list, rather than the one I’m selecting.

I posted on stackoverflow and someone suggested my React keys may not be right but they seem to be (I’m using map to loop through the items).

I was wondering if it’s because I’m using uncontrolled React forms with refs, instead of controlled. But I tried changing one of them; this also didn’t work.

So now I’m wondering if using findOneAndDelete() with mongoose for the DELETE request is correct or not.

Anyone else run into this problem before? The project is here - https://mealtracknfind.glitch.me/

If it were me, I’d put some logging in the nodeexpressapi project, in meals.js, on the delete function, to check my expectations are being met for IDs:

router.delete(
  "/:id",
  async (req, res) => {
    try {
      const filter = { _id: mongoose.Types.ObjectId(req.params.id) }
      // Check ID and filter obj
      console.log(req.params.id, filter);
      const meal = await Meal.findOneAndDelete(filter, (err, meal) => {
          err ? res.json({ success: false, err }) : res.status(200).json(meal)
        })
    } catch (err) {
      console.error(err.message)
      res.status(500).send("Server Error")
    }
  }
)

I can’t comment on your react code unfortunately :slight_smile:

Hope you find the answer! :blush:

I agree with SteGriff as a step one I always confirm what I believe my parameters are and the response I get.

The second thing I would do is add more data to your filter not because it is needed (we know it shouldn’t be) but because if you include another property you could see if the same thing happens.

You could also try coding it as a Find followed by a Delete using just the id, again just to confirm that generally things are behaving as you expect.

Thanks guys! I need to get better at debugging things. I am not getting errors from the backend but I realized that if I try to add a duplicate book (on a different form) the latest version of Mongoose doesn’t stop it and I get a React error that I have 2 items with the same key. If I downgrade Mongoose, it will at least refresh the page and not let me add 2 of the same book, which is what I want. So I’ve opted to just downgrade for now.

I am still seeing the same issue in terms of the first item deleting, though. I tried changing it to findById and used remove() and that had the same result. I’ll play around with it some more.

What I would do next is to create a simple test that hardcoded only what I needed to perform that test. No form inputs, I might not use the existing model objects even. Isolate everything into a test that adds two items, lists them and deletes the second one.

If there is no other support code involved you would at least be able to post a short example to a MongoDB support group who could duplicate it and perhaps identify the reason.

That would be useful! It turns out if I take out the modal, the ‘delete’ works properly on just the button. But…I’d like to keep the modal. I’m going to dig around later and see if anyone else had this happen with Bootstrap. Might also split it back up into 2 components and use more hooks as per this article: https://www.robinwieruch.de/react-remove-item-from-list

I had a feeling initially it wasn’t Mongoose since these are simple CRUD operations. Mongoose does have a lot of bugs though :joy:

Hola! creo que usas el método equivocado, al usar findOneAndDelete(), no encuentra al elemento por su ID, encuentra al primero de la lista que sea similar. En todo caso puedes probar con el método findByIdAndDelete(), este método me funcionó. Espero que te sirva :smiley:

Thanks, you’re right that they are a bit different, but I had it filtering by ID, which is the same thing according to Mongoose. I ended up changing it to findOne() and that worked.

router.delete(
  '/:id',
  passport.authenticate('jwt', { session: false }),
  async (req, res) => {
    try {
      const meal = await Meal.findOne({
        _id: mongoose.Types.ObjectId(req.params.id)
      })
      if (!meal) return res.status(404).json({ msg: 'Meal does not exist.' })
      await meal.remove()
      res.json(meal)
    } catch (err) {
      console.error(err.message)
      res.status(500).send('Server Error')
    }
  }
)
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.