AkashGupta
AkashGupta

Reputation: 3

Update existing items in nested array using mongoose

There is a schema as mentioned below. I'm trying to update the existing todo.task.

The problem is, I am storing the path as var done = 'todos.'+todoIndex+'.tasks.'+taskIndex+'.done' and it does not work. I was looking to update like todos.0.tasks.0.done:req.body.done, but it doen't work at all.

(todoIndex and taskIndex are in string which stores the index values)

What is the correct way of doing this?

var mongoose = require('mongoose');

var todoSchema = {
    authorId : mongoose.Schema.Types.ObjectId,
    date:{
        type:Date
    },
    title : {
        type : String
    },
    description : {
        type : String
    },
    todos : [ {
        created : {
            type : Date
        },
        updated : {
            type : Date
        },
        title : {
            type : String
        },
        description : {
            type : String
        },
        done:{
            type:Boolean
        },
        deadline:{
            type:Date
        },
        tasks : [ {
            done : Boolean,
            task : String
        } ]
    } ]
}

module.exports = new mongoose.Schema(todoSchema);
module.exports.todoSchema = todoSchema;

I was trying to build the Api like this:

api.put('/notebooks/todo/update/:pid',wagner.invoke(function(Todo,User){
        return function(req,res){
            var taskIndex=req.body.taskIndex;
            var todoIndex=req.body.todoIndex;
            var done = 'todos.'+todoIndex+'.tasks.'+taskIndex+'.done';
            console.log(done);
            Todo.update({_id:req.params.pid},{$set:{
                done : req.body.done,
            }}, function(err,done){
                console.log( done);
            })
    }}));

Upvotes: 0

Views: 84

Answers (1)

robertklep
robertklep

Reputation: 203231

If you're using a recent Node version, you can use a computed property name:

Todo.update({ _id : req.params.pid }, { $set : { [ done ] : req.body.done } }, ...

Otherwise, you need to use an intermediate object:

var done  = 'todos.'+todoIndex+'.tasks.'+taskIndex+'.done';
var obj   = {};
obj[done] = req.body.done;
Todo.update({ _id : req.params.pid }, { $set : obj }, ...

Upvotes: 1

Related Questions