AkashGupta AkashGupta - 5 months ago 33
Node.js Question

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);
})
}}));

Answer

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 }, ...
Comments