MongoDB (mongoose) in Nodejs - save acts strange - node.js

I use this in router in nodejs to save a value posted on html.
router.post('/', function(req,res,next) {
User.findOne({ '_id': req.user._id }, function (err, doc){
console.log(doc);
if(err) { console.log(err);
res.json({success: false, msg: 'Error: database error.'}); };
doc.profile.name = req.body.value;
doc.save();
console.log(doc);
return res.json({success: true});
});
});
when I output the doc after I save it works perfectly but after I refresh or look at the database itself it did not modify at all.
It used to work. What I saw and I don't get why, is if I use doc.save() , then again doc.save() two times it works and updates the data eventually.
Can someone explain what may happen?

So for someone who can not debug the problem , you can use .
.save(function (err,obj){
console.log(err);
});
for me it was a problem with the structure of my db because I've added some enums and I had empty field so that caused the problem.

Related

MongoDB $pull Query Doesn't Work Properly

Guys I want to make a unfollow request with $pull qıery but it doesnt work. How to solve this?
Also this method works fine with $push query when I want to follow request user but it doesnt work with $pull.
My app.js:
app.post('/unfollow/:id', function(req, res){
User.find(req.user
).exec(function(err, user){
if(err){
console.log(err);
}
User.find({"username":req.params.id}, function(err, friend){
if(err){
console.log(err);
}
User.update(user,{$pull: { follow: friend}}, function(err){
if(err){
console.log(err);
}else{
res.send("Success")
}
});
});
});
});
This is my how user's follow look like:
{ follow:
[ 5edfe8f3bfc9d677005d55ca,
5edfe92fbfc9d677005d55cc,
5ee2326cc7351c5bb0b75f1a ],
I will take friend id from this array.
And my user model(Follow part):
follow:[{
type: ObjectId,
}]
If pull doesnt work can you suggest me queries or ways to do unfollow request.
User.find({ username: req.params.id } would return a document but looks like you do store ObjectIds in follow field. I except changing $pull: { follow: friend } to $pull: { follow: friend._id } should solve the problem.

Why isn't it updating

User.update({_id: req.params.id}, userTemp).then(function(){
User.findOne({_id: req.params.id}).then(function(user){
res.send(user);
});
});
So this code is running but it doesn't actually change the value in the database. I should replace the previous user with a new one however it does not.
As you can find out in documentation update can be used on document when you already have that document: doc
For your example I would rather use findByIdAndUpdate like this:
User.findByIdAndUpdate(req.params.id, userTemp, function(err, user) {
res.send(user);
})

Update data in MongoDB with Mongojs using findAndModify()

Yet another first-timer problem here. This gets data from a database and displays it in some text fields (that part is not shown in the code below) and after the user edits it the data should be updated in the database via the findAndModify() method and I think this is where the issue lies. There are no errors, it just doesn't do anything. EDIT The following error is received: MongoError: Either an update or remove=true must be specified
server.js
MongoClient.connect("mongodb://user:secretPassword#aws-us-east-1-portal.7.dblayer.com:10712,aws-us-east-1-portal.10.dblayer.com:10316/database", function(err, db) {
if (err) throw err;
var contactList = db.collection("contactList");
app.put('/contactList/:id', function(req, res) {
var id = req.params.id;
console.log("edited: " + req.body.name); //works up until here
contactList.findAndModify({
query: {_id: mongojs.ObjectId(id)},
update: {$set: {name: req.body.name, email: req.body.email, number: req.body.number}},
new: true
}, function (err, doc) {
res.json(doc);
})
});
controller.js
$scope.update = function() {
$http.put('/contactList/' + $scope.contact._id, $scope.contact).success(function(response) {
refresh();
})
};
If this were me I would first do a couple of things:
Before your call to findAndModify just do a simple find using your query. Make sure you can actually find the object using your query. If that works you know that the 'find' part of the findAndModify is probably ok.
Do some console logging inside the callback handler of the findAndModify call. As it stands you do not do anything if an err is returned from the findAndModify call. It is possible your call is returning an error that you are just ignoring and it may provide some additional insight into your problem.
I would try these two first and see if it helps.
Update:
Example using native:
collection.findAndModify(
{ field: 'some value' },
[],
{ $set: { field2: 'some new value' } },
{ new:true },
function(err, doc) {
//handle err and doc
});

Mongoose Pre Command not working as Expected

Hi I am New to Mongoose And trying to use pre command to Convert a given password in String to Hash values before saving it in the database. I am not Getting any Syntax error but my password is not getting converted into Hash IDS.
My Controller Code is as follows:
User.save(req.body,function(err,data){
if (err) {
res.json({
sucess:false,
exception:err
});
}
else{
res.json({
sucess:true,
User:data
});
}
});
User.pre('save',function(next){
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt){
if(err){
return res.json({
success:false,
exception:err
});
}
bcrypt.hash(password, salt, function(err, hash) {
if(err){
return res.json({
success:false,
exception:err
});
}
password=hash;
});
});
next();
});
Using Node inspector I found out that command line is not entering the User.pre .So Can somebody let me know where I am making a mistake.
There's various things wrong with your code, the main part being that hooks should be attached to the schema and not the model, which seems to be what you're doing.
Also, it looks like you're trying to add a pre-save hook for every request, which is not how hooks are supposed to work: they should be declared just once, on the schema (as said above) and before you create the model.
The order should be similar to this:
var UserSchema = new mongoose.Schema(...);
UserSchema.pre('save', ...);
var User = mongoose.Model(UserSchema);
This means that you can't send an error response from your pre-save hook, as you're trying to do now, but you don't really want that anyway IMO (you should keep your Mongoose schema/models separated from your Express route handlers). Instead, catch any errors that are thrown during .save() and handle them there.
To give an idea on what a proper hook might look like, here's an example (I took a guess as to your User schema so it may be using the wrong field names):
UserSchema.pre('save', function(next) {
var document = this;
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
bcrypt.hash(document.password, salt, function(err, hash) {
if (err) return next(err);
document.password = hash;
next();
});
});
});

Mongoose Returned Model can't be updated

I'm pretty new to Mongoose/Mongo and node.js, so I suspect this is just a misunderstanding on my side, but...
The code sample below is the smallest failing example, not specifically my use case.
var User = app.db.model('User');
User.find({email: 'm8#test.com'}, function (err, models) {
models[0].update(function(err, mod) {
console.log(err.message)
});
});
This results in the following error: After applying the update to the document {_id: ObjectId('54647402cb955748153ea782') , ...}, the (immutable) field '_id' was found to have been altered to _id: ObjectId('546d9e0e539ed9ec102348f9')
Why is this happening? I would have thought calling update on the model returned from the initial find would have been fine.
Please note: in my use case there are things happening in between the find and the update. Specifically, I'm doing something similar to:
model.property.push(objectId)
Which I then want to commit via the update.
I'm sure this is a straight-forward issue, but I can't see anywhere in the docs I may be getting it wrong.
All help appreciated.
UPDATE:
What I actually needed to do was:
var User = app.db.model('User');
User.find({email: 'm8#test.com'}, function (err, models) {
models[0].save(function(err, mod) {
console.log(err.message)
});
});
Using 'save' rather than 'update'
I don't know if I understood
Find and Update ( for example using express )
var email = req.params.email;
User.find({email:email}, req.body, function(err,user){
if(err){
throw err;
}
//you do stuff like this
var obj = {
password:'new pass',
username:'username'
}
//use save if you want validate
User.update(user[0],obj,function(err, mod) {
console.log(err)
});
});
Only Update: ( for example using express )
User.update({email:email}, req.body, {}, function(err,user){
if(err){
throw err;
}
res.send(200, {
message : 'User updated ' + user
});
});
Remember that:
A model is a compiled version of the schema.
I hope this can help you

Resources