cfibla
cfibla

Reputation: 35

How can I delete an item from an Object in NodeJs/express/mongoose?

I know this has been asked before, but no one of the answers worked for me. In my App, I have a users collection in MongoDb. These users collection have an array field named 'segActuacions' that can be modified within a form. This form sends this Object to router:

{
    "segActuacions.0.date": "27/09/2016",
    "segActuacions.0.body": "first item",
    "segActuacions.1.date": "27/09/2016",
    "segActuacions.1.body": "second item"
}

router has this line to go to controller:

router.delete('/seg_act_upd_EE/:id/actDel/:i', 
    sessionController.loginRequired,  
    userController.actuaDelete
);

where ':id' is User-id, and ':i' is the index of segActuacions

Controller has this code:

exports.actuaDelete = function (req, res) {
    var userId = req.params.id;
    var userI = req.params.i;
    var usr = req.body;

    delete usr['segActuacions.userI.date'];
    delete usr['segActuacions.userI.body'];

    models.User.findByIdAndUpdate(userId, usr, function (error, user){
        if (error) res.json(error);
        res.redirect('/list_EE');
    });
}

I want to delete the fields 'i' of the Object (for instance: if i=0, i'd like to delete "segActuacions.0.date" and "segActuacions.0.body", ...but nothing happens.

Upvotes: 2

Views: 5074

Answers (2)

chridam
chridam

Reputation: 103365

If you are simply looking to delete the keys from the req.body object and subsequently update your collection with the remaining keys then follow this example:

exports.actuaDelete = function (req, res) {
    var userId = req.params.id;
    var userI = req.params.i;
    var usr = req.body;

    delete usr["segActuacions."+ userI +".date"];
    delete usr["segActuacions."+ userI +".body"];

    models.User.findByIdAndUpdate(userId, usr, function (error, user){
        if (error) res.json(error);
        res.redirect('/list_EE');
    });
}

To remove the fields from the collection, the best way is to use $unset operator because delete removes the keys from an object and updating the collection with the updated object will not remove the actual fields from the collection.

In essence you use the dot notation to correctly identify the field to remove. For example, you would want to achieve the following mongo shell update operation:

db.users.update(
    { "_id" : userId },
    {
        "$unset": {
            "segActuacions.1.date" : "",
            "segActuacions.1.body" : ""        
        }
    }
)

This will remove the fields from the element in position with index 1 in the segActuacions array.

Tying all this with your controller method, you can construct an update object that is similar to

{
    "$unset": {
        "segActuacions.1.date" : "",
        "segActuacions.1.body" : ""        
    }
}

such as

exports.actuaDelete = function (req, res) {
    var userId = req.params.id;
    var userI = req.params.i;
    var usr = {};

    usr["segActuacions."+ userI +".date"] = "";
    usr["segActuacions."+ userI +".body"] = "";

    models.User.findByIdAndUpdate(userId, { "$unset": usr }, function (error, user){
        if (error) res.json(error);
        res.redirect('/list_EE');
    });
}

Upvotes: 1

andresk
andresk

Reputation: 2845

Note your delete wouldn't work because you are using userI as a string and not using the variable value. Also update will just update the fields that are in the object.

But I think you should use $unset, like the following:

var updateObj = {};
updateObj['segActuacions'] = {};
updateObj['segActuacions'][userI] = {};
updateObj['segActuacions'][userI]['body'] = '';
updateObj['segActuacions'][userI]['date'] = '';

var update = { $unset:  updateObj };

models.User.findByIdAndUpdate(userId, update, function (error, user){
    if (error) res.json(error);
    res.redirect('/list_EE');
});

(This code can be improved and wasn't tested)

Upvotes: 0

Related Questions