1

I'm trying to remove an object from an array in a document using mongoose.

This is an example of an entry:

{
  _id: "12345",
  folder: {
    name: "Folder1",
    files: [
      {
        fileName: "File 1",
        fileID: "6789",
        folderID: "12345"
      }
    ],
    active: true
  }
}

This is what I am currently doing to remove the file from the array. The Attachment.unlink is what removes the file from the gridfs filestore. That part of the code works. My object however will not remove from the array.

router.delete("/filesystem/:id", (req, res, next) => {
  Attachment.unlink(req.params.id, (error, attachment) => {
    if (!attachment) return res.status(404);
    if (error) return next(error);
    Folder.findByIdAndUpdate(
      {
        _id: req.body.folderID
      },
      {
        $pull: {
          "folder.files": {
            $elemMatch: { fileID: req.params.id }
          }
        }
      },
      { multi: true, safe: true },
      (error, folder) => {
        if (error) return next(error);
        return res.status(200).json({
          folder
        });
      }
    );
  });
});

I have also tried to use update rather than findByIdAndUpdate. How do I remove an object from the array where the fileID is 6789?

craigsale29
  • 35
  • 1
  • 8

1 Answers1

0

You should be able to use array.pull (see https://mongoosejs.com/docs/api.html#mongoosearray_MongooseArray-pull)

Below is a sample where I've modified your code and used async/await instead of callbacks.

router.delete("/filesystem/:id", (req, res, next) => {
  Attachment.unlink(req.params.id, async (error, attachment) => {
    if (!attachment) return res.status(404);
    if (error) return next(error);

    try {
      const folder = await Folder.findById(req.body.folderID);
      folder.folder.files.pull({ fileID: req.params.id });
      await folder.save();

      return res.status(200).json({
        folder
      });
    } catch (error) {
      return next(error);
    }
  });
});
Adam Gerthel
  • 663
  • 3
  • 9
  • 24
  • This gets the value of the whole array – craigsale29 Jun 07 '19 at 14:54
  • Are you certain? Pull should remove it from the object. Obviously you have to complete the save as per my example, otherwise the change won't be saved to the database. – Adam Gerthel Jun 07 '19 at 14:59
  • I just realized that your Folder model has a "folder" field, so it's `folder.folder.files.pull` and not `folder.files.pull`. – Adam Gerthel Jun 07 '19 at 15:04
  • Yes I recognized that and tried it the correct way. I believe the pull may not be working because it is not another Schema or an ObjectID like the docs state – craigsale29 Jun 07 '19 at 15:07
  • I dunno, I have a feeling that something else is wrong since neither array.pull or findByIdAndUpdate is working for you. Can you find the object in the array if you use for example `const file = folder.folder.files.find(file => file.fileID === req.params.id)` in my code sample? Are you sure the field name is fileID? Are you sure the value isn't wrong (i.e. req.params.id is a Number but fileID expects a String – Adam Gerthel Jun 07 '19 at 15:19