Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

am using mongoose 3.8.8 and I have been trying to update a subdocument and haven't made progress #2686

Closed
atumachimela opened this issue Feb 17, 2015 · 24 comments
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary

Comments

@atumachimela
Copy link

pin schema 👍
var PinSchema = new Schema({
name: {
type: String,
trim: true,
required: 'Pin must have a name'
},
url: String,
image: {
type: String,
required: 'Pin must have an Image'
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
board: {
type: Schema.ObjectId,
ref: 'Board'
},
likes: [LikesSchema],
comments: [CommentSchema],
created: {
type: Date,
default: Date.now
}

});

exports.update = function(req, res) {
_.forEach( req.pin.comments, function(comment, key) {
if (req.params.commentId.toString() === comment._id.toString()) {
comment.text = req.body.text;
}
});

//we have a problem : update on comment does not persist to the doc in db.
console.log('newPin', req.pin.comments);
req.pin.save(function(err, pin) {
if (err) {
return res.status(400).send({
message: 'Could not update a comment'
});
} else {
res.json(pin);
}
});
};

@atumachimela
Copy link
Author

updating a comment does not persist to the database.
Please I need help as soon as possible

@atumachimela atumachimela changed the title am using mongoose 3.8.8 and I have been trying to update an embedded document and haven't made progres am using mongoose 3.8.8 and I have been trying to update a subdocument and haven't made progress Feb 17, 2015
@vkarpov15
Copy link
Collaborator

Where is this issue actually happening? Is the _.forEach() failing to find the correct comment or is the save() call just not saving the update?

@atumachimela
Copy link
Author

The save() call not saving the update.
This is the response from the save call

{
"_id": "54e1ff0ed14261dd2f7c8b3c",
"user": "54da299dfd256dc879ee3c32",
"name": "ekosagdsagsdg",
"image": "aa.png",
"url": "aa.png",
"board": "54e1fe98d14261dd2f7c8b39",
"__v": 3,
"created": "2015-02-16T14:30:38.328Z",
"comments": [
{
"text": "sure",
"created": "2015-02-16T14:32:49.579Z",
"_id": "54e1ff91d14261dd2f7c8b3e",
"user": "54da299dfd256dc879ee3c32"
}
],
"likes": []
}

@atumachimela
Copy link
Author

But when we do a find() on the same pin we have
{
"count": 1,
"data": [
{
"_id": "54e1ff0ed14261dd2f7c8b3c",
"user": "54da299dfd256dc879ee3c32",
"name": "ekosagdsagsdg",
"image": "aa.png",
"url": "aa.png",
"board": null,
"__v": 3,
"created": "2015-02-16T14:30:38.328Z",
"comments": [
{
"text": "niaja",
"created": "2015-02-16T14:32:49.579Z",
"_id": "54e1ff91d14261dd2f7c8b3e",
"user": "54da299dfd256dc879ee3c32"
}
],
"likes": []
}
]
}

@vkarpov15
Copy link
Collaborator

Do you get an error in the save() callback or does it fail silently? Also, can you show me what the document looks like in the mongodb shell?

@vkarpov15 vkarpov15 added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Feb 17, 2015
@atumachimela
Copy link
Author

I don't get an error in the save() callback. The object that gets returned in the call back shows that it was saved but when the document is pulled again the change doesn't persist.

This is the object that get returned in the callback

{
"_id": "54e1ff0ed14261dd2f7c8b3c",
"user": "54da299dfd256dc879ee3c32",
"name": "ekosagdsagsdg",
"image": "aa.png",
"url": "aa.png",
"board": "54e1fe98d14261dd2f7c8b39",
"__v": 3,
"created": "2015-02-16T14:30:38.328Z",
"comments": [
{
"text": "sure",
"created": "2015-02-16T14:32:49.579Z",
"_id": "54e1ff91d14261dd2f7c8b3e",
"user": "54da299dfd256dc879ee3c32"
}
],
"likes": []
}

@atumachimela
Copy link
Author

while this is the object that remains unchanged after the save when the document is pulled from the database

{
"count": 1,
"data": [
{
"_id": "54e1ff0ed14261dd2f7c8b3c",
"user": "54da299dfd256dc879ee3c32",
"name": "ekosagdsagsdg",
"image": "aa.png",
"url": "aa.png",
"board": null,
"__v": 3,
"created": "2015-02-16T14:30:38.328Z",
"comments": [
{
"text": "niaja",
"created": "2015-02-16T14:32:49.579Z",
"_id": "54e1ff91d14261dd2f7c8b3e",
"user": "54da299dfd256dc879ee3c32"
}
],
"likes": []
}
]
}

@atumachimela
Copy link
Author

notice that the text field did not change above as compared to the what we have in the response we get from save() callback

@vkarpov15
Copy link
Collaborator

What are you using to pull the data from the database afterward? Can you show me the mongo shell output?

@atumachimela
Copy link
Author

we are using mongoLab . We usually use the mongo lab GUI

@vkarpov15
Copy link
Collaborator

Try doing mongoose.set('debug', true): this will show the queries and saves going back and forth between mongoose and mongodb server. Can you show me the output from running with that? You should see output that looks like this on your command line:

Mongoose: items.findOne({}) { fields: undefined } 

@atumachimela
Copy link
Author

This is the output of running -: mongoose.set('debug', true)
Mongoose: users.findOne({ _id: ObjectId("54e4a575ee666514594f5358") }) { fields: { password: 0, salt: 0 } }
Mongoose: pins.findOne({ _id: ObjectId("54e1ff0ed14261dd2f7c8b3c") }) { fields: undefined }
Mongoose: pins.update({ _id: ObjectId("54e1ff0ed14261dd2f7c8b3c") }) { '$unset': { text: 1 } } {}

@vkarpov15
Copy link
Collaborator

hmmm looks like your save operation is getting translated to an unset. That's very strange. Can you output the internal state of the pin document right before you call save()?

// Put this log statement to output the internal state of the doc before save
console.log(require('util').inspect(req.pin.$__));
// Save code
req.pin.save(function(err, pin){
  // ...
});

@james075
Copy link

any update on this issue ?

@vkarpov15
Copy link
Collaborator

Nope. Are you having the same issue?

@vkarpov15
Copy link
Collaborator

No update for a while. Re-open if still an issue.

@iMarvinS
Copy link

Any update on this issue? I´m experiencing exactly the same one.

@vkarpov15
Copy link
Collaborator

Provide code sample please.

@iMarvinS
Copy link

Of course.
Here is the part for interaction with the model:

userRouter.route("/:user_id")
         .put(function(req, res, next){
             User.findById(req.params.user_id, function(err, user){
               if(err) return next(err);

               if(!user){
                  var err = new Error('Not Found');
                  err.status = 404;
                  return next(err); 
               }

               user.state.isHome = parseInt(req.body.isHome, 10) > 0 ? true : false;
               user.state.modified = new Date();

               user.save(function(err, updated){
                  if(err) return next(err);

                  var userObj = user.toObject();
                  delete userObj.passwd;

                  res
                     .status(200)
                     .send(userObj);
               });

            });

         });

This is the schema itself:

var userSchema = new Schema({
   name: String, 
   mail: String,
   passwd: String,
   state: { type: Object, default: {
      isHome: false,
      updated: new Date()
   }}

});

I´ve installed mongoose via npm ("mongoose": "4.x.x").

@vkarpov15 vkarpov15 reopened this May 14, 2015
@vkarpov15 vkarpov15 added this to the 4.0.5 milestone May 14, 2015
@vkarpov15
Copy link
Collaborator

@iMarvinS Hmm the below script works as expected for me:

var assert = require('assert');
mongoose.set('debug', true);

mongoose.connect('mongodb://localhost:27017/gh2686');

var Schema = mongoose.Schema;

var userSchema = new Schema({
   name: String, 
   mail: String,
   passwd: String,
   state: { type: Object, default: {
      isHome: false,
      updated: new Date()
   }}

});

var User = mongoose.model('User', userSchema);

User.create({}, function(error, user) {
  assert.ifError(error);
  user.state.isHome = true;
  user.state.modified = new Date();

  user.save(function(err, updated) {
    User.findOne({ _id: updated._id }, function(error, user) {
      console.log(JSON.stringify(user));
      process.exit(0);
    });
  });
});

Output:

Mongoose: users.insert({ _id: ObjectId("55677bcd68b52a1c5b80e020"), state: { updated: new Date("Thu, 28 May 2015 20:34:21 GMT"), isHome: false }, __v: 0 })   
Mongoose: users.update({ _id: ObjectId("55677bcd68b52a1c5b80e020") }) { '$set': { state: { modified: new Date("Thu, 28 May 2015 20:34:21 GMT"), updated: new Date("Thu, 28 May 2015 20:34:21 GMT"), isHome: true } } }  
Mongoose: users.findOne({ _id: ObjectId("55677bcd68b52a1c5b80e020") }) { fields: undefined }  
{"_id":"55677bcd68b52a1c5b80e020","__v":0,"state":{"isHome":true,"updated":"2015-05-28T20:34:21.261Z","modified":"2015-05-28T20:34:21.300Z"}}

Can you clarify what sort of unexpected behavior you're seeing? "Doesn't work" is usually not sufficiently clear.

@vkarpov15 vkarpov15 added the can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. label May 28, 2015
@iMarvinS
Copy link

Your example seems to work fine but check out this one:

var mongoose = require('mongoose');
var assert = require('assert');
mongoose.set('debug', true);

mongoose.connect('mongodb://192.168.178.24:27017/test');

var Schema = mongoose.Schema;

var userSchema = new Schema({
   name: String, 
   mail: String,
   passwd: String,
   state: { type: Object, default: {
      isHome: false,
      updated: new Date()
   }}

});

var User = mongoose.model('User', userSchema);

User.findOne({ _id: '55698c7e8abce45423083bf9' }, function(error, user) {
  assert.ifError(error);

  console.log(user);
  user.state.isHome = true;
  user.state.modified = new Date();
  console.log(user);

  user.save(function(err, updated) {
    User.findOne({ _id: updated._id }, function(error, user) {
      console.log(JSON.stringify(user));
      process.exit(0);
    });
  });
});

If I want to find a specific user, modify its properties and then save the user object to mongodb it simply doesn´t save the modified properties to the server.

Look at the output:
bildschirmfoto 2015-05-30 um 12 24 20

@iMarvinS
Copy link

I just found out about the doc.markModified() method.
After setting the properties I put this:

 user.markModified('state.isHome');
 user.markModified('state.modified');

Now it works like expected.
The properties of the found user object can be modified and everything will be saved to persistence.
Can there be a way to automate the doc.markModified() in the next release?

From my side this topic can be closed now.

@vkarpov15
Copy link
Collaborator

Ah you're right, that's slightly different. You have to call markModified for now, because mongoose doesn't watch fields under type: Object - there's no way to do that in a general way without ES6 proxies or ES7 Object.observe(). I'm not entirely sure why my example actually worked, I need to investigate that.

@vkarpov15 vkarpov15 modified the milestones: 4.0.6, 4.0.5 Jun 1, 2015
@vkarpov15 vkarpov15 added bug? and removed can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. labels Jun 1, 2015
@vkarpov15
Copy link
Collaborator

Looking a bit more closely at this, you need to call markModified() yourself because mongoose can't watch for changes in type: Mixed in current version of JS language standard. See docs on mixed type.

Reason why my example worked was that the doc was when I modified isHome and modified, that document already had the state path as 'modified' because of the default.

@vkarpov15 vkarpov15 removed the bug? label Jun 8, 2015
@vkarpov15 vkarpov15 removed this from the 4.0.6 milestone Jun 8, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary
Projects
None yet
Development

No branches or pull requests

4 participants