8

I have a node object that looks like this:

{
   "_id":"58b336e105ac8eec70aef159",
   "name":"my node",
   "ip":"192.168.1.1",
   "__v":0,
   "configuration":{
       "links":[
         {
            "linkName":"athena_fw_listen_tcp_5555",
            "_id":"58b336e105ac8eec70aef15d",
            "local":true
         },
         {
            "linkName":"athena_fw_listen_udp_5554",
            "_id":"58b336e105ac8eec70aef15c",
            "local":true
         }
      ]
   }
}

I am sending a delete request to my express server that looks like this: DELETE http://localhost:9000/api/nodes/58b336e105ac8eec70aef159/links/58b336e105ac8eec70aef15d

I followed instructions in $pull mongodb documentation and I also tried this

But it does not seem to work, as I keep receiving: 500 (Internal Server Error)

This is how the code on my express side looks like:

exports.destroyLink = function(req, res) {
    Node.findById(req.params.id, function(err, node) {
        if (err) { return handleError(res, err); }
        if (!node) { return res.status(404).send('Not Found'); }
        console.log("Node", JSON.stringify(node))
        console.log("Params", req.params)

        node
            .update({ '_id': req.params.id }, { $pull: { 'configuration': { 'links': { '_id': req.params.linkId } } } }, false, true)
            .then(err => {
                if (err) { return handleError(res, err); }
                return res.status(204).send('No Content');
            });
    })
};

The express router contains this: router.delete('/:id/links/:linkId', controller.destroyLink);

So I am expecting id and linkId as params, I use id (_id: req.params.id) to target a specific node and linkId (_id: req.params.linkId) to target a specific link, but it doesn't work!

Need help resolving the issue, I don't know what I am missing here!

6
  • Can you try { $pull: { 'configuration.links': { '_id': req.params.linkId } } } ? Commented Feb 26, 2017 at 20:52
  • @Veeram I tried what you suggested before and I tried it now, but it does not work! :'( I updated my line of code to this: node.update({ '_id': req.params.id }, { $pull: { 'configuration.links': { '_id': req.params.linkId } } }, function(err, data) { console.log("Data", data) if (err) { return handleError(res, err); } return res.status(204).send('No Content'); }); this what I get in the console: Data { ok: 1, nModified: 0, n: 1 } Commented Feb 26, 2017 at 21:06
  • okay not sure how to fix it as is. On a side note, configuration key is redundant in your document. You can remove it if it works for you and then you can access links as mentioned in docs. Commented Feb 26, 2017 at 21:14
  • Oh, that's because I am planning on adding other elements to configuration, so I would prefer keeping it this way. Thank you anyways, I appreciate it! Commented Feb 26, 2017 at 21:18
  • You are welcome. So I looked into further. I don't much about mongoose. You can verify the _id is defined as String in your mongoose schema. If it is defined as ObjectId then you have to convert req.params.id and req.params.linkId into ObjectId before passing it to query. Btw the query edit I suggested above works fine from mongo shell. Commented Feb 26, 2017 at 21:41

5 Answers 5

17

Hi all and thank you for your help. I finally got it to work!!!

After almost 3 hours of troubleshooting :'( :'( this is the solution that used:

exports.destroyLink = function(req, res) {
Node.findByIdAndUpdate(
    req.params.id, { $pull: { "configuration.links": { _id: req.params.linkId } } }, { safe: true, upsert: true },
    function(err, node) {
        if (err) { return handleError(res, err); }
        return res.status(200).json(node.configuration.links);
    });
};

Instead of findById then update the node, I did both using findByIdAndUpdate. It' working perfectly now!!!

I still don't find an explanation for the other version though. But anyways glad it's working this way.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, after spending lots of time your answer resolved my issue . To make findByIdAndUpdate work I had to set useFindAndModify to false ( mongoose.connect(uri, { useFindAndModify: false }); )
3

I had a similar issue getting a query like yours working. I think your query is not finding the id you're looking for. If you want to find an object in mongo by '_id' it needs to be passed in as an ObjectId. Try modifying things so it looks like this:

const mongo = require('mongodb');
var oId = new mongo.ObjectID(req.params.id);
update({ '_id': oId }, { $pull: { 'configuration': { 'links': { '_id': req.params.linkId } } } }, false, true)

1 Comment

I tried converting the parameter to both mongoose.Types.ObjectId and as you suggested above mongo.ObjectID. As far as I understande from this line below, the delete request was accepted and successful. DELETE /api/nodes/58b356a18f54358c5b9c2123/links/58b356a18f54358c5b9c2127 204 13ms However, the node object appears to still have the link_to_delete in its 'configuration.links' array.
1

I never got this working using the mongodb $pull operator. An alternative is to find the document then update the array using the mongoose pull method. The pull method can take an id string as its single argument and knows how to handle it. For this example using promises the code would look something like:

exports.destroyLink = function(req, res) {
  Node.findById(req.params.id)
    .then(node => {
      node.configuration.links.pull(req.params.linkId)
      return node.save()
    .then(node => res.send(node.configuration.links))
}

The mongoose docs for pull

Comments

0

I got the .update mongoose function to work by changing to this:

{ $pull: { 'configuration': { 'links': { '_id': ''+req.params.linkId+'' } } } }

Once you concatenate that, it'll pull it from the array.

Comments

0

For my problem, this worked

await FormSchema.updateOne({formName: name}, {$pull: {fields: {fieldName: fieldName}}}).exec();

and here is what my schema looks like

{
"fields": [
    {
        "contentType": "Text",
        "fieldName": "First Name",
        "textType": "short",
        "isUnique": false
    },
    {
        "contentType": "Boolean",
        "fieldName": "Contact Me"
    }
],
"_id": "61f71efd14cafb5a50ba365f",
"formName": "Contact",
"__v": 4

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.