0
votes

I have a Model, Users, and each user has an array of objects called habits.


{
  _id: 606f1d67aa1d5734c494bf0a,
  name: 'Courtney',
  email: 'c@gmail.com',
  password: '$2b$10$WQ22pIiwD8yDvRhdQ0olBe6JnnFqV2WOsC0cD/FkV4g7LPtUOpx1C',
  __v: 35,
  habits: [
    {
      _id: 6081d32580bfac579446eb81,
      name: 'first',
      type: 'good',
      days: 0,
      checked: false
    },
    {
      _id: 6081d32f80bfac579446eb82,
      name: 'seconds',
      type: 'bad',
      days: 0,
      checked: false
    },
  ]
}

From my client side, I send over a list of ids of the habits I want to delete out of the array, that looks like this..

[
  '6081d32580bfac579446eb81',
  '6081d32f80bfac579446eb82',
]

I am trying to find a way to delete the IDs in the habits array, deleting only the habits whose IDs are sent in the array above.

Here is what I have tried....

router.post('/delete', validate, async (req, res) =>{
  const user = await User.findById(req.user._id)
  const idList = req.body.ids.checkedItems

  const updatedList = user['habits'].filter(habit=> {
    return !idList.includes(`${habit._id}`)
  })

  user['habits'] = updatedList;

    try {
      await user.save()
      res.send(updatedList)

    } catch (err) {
      res.status(400).send(err)
    }
  })

-idList is the array of ids as strings.
-user['habits'] accesses the list from the document, user.
-my filter method only returns the habits that are NOT included in the idList array. Because the Ids in the array are the ones to be deleted.

This solution is obviously just vanilla javascript, what I am looking for is if anyone knows how to achieve this using mongoose.js syntax.

I think you could do this by using deleteMany or deleteOne on the Model, but I am not sure how to achieve this.

Thank you for taking the time to help or give suggestions.

2

2 Answers

0
votes

The solution that worked for me in the end is to use the Model method 'findByIdAndUpdate'.

const { itemsToDelete } = req.body

  User.findByIdAndUpdate(req.user._id,
    { $pull: { habits: { _id: itemsToDelete } } },
    { new: true , useFindAndModify: false},
    function (err, data) {
      if (err) {
        res.send(err)
      } else {
        res.send(data.habits)
      }
    }
  )
0
votes

You can use a combination of $pull and $in for this.

User.update({_id: userId},
{
  $pull: {
    habits: {
      _id: {
        $in: [
          ObjectId("6081d32580bfac579446eb81"),
          ObjectId("6081d32f80bfac579446eb82")
        ]
      }
    }
  }
})