Updating mongodb and rendering it - node.js

I am learning mongodb, node.js and mongoose and want to update a mongodb and then display it on my browser. However my code only displays the results prior to my update even though I know the database has already been updated.
So for example I have two students called John and Tom, but when I update it with a third student called Fred and try to render the results, it only gives me John and Tom's details. Here is my code:
create: function(req, res) {
console.log('creating model');
var newStud = new Models.Student({
surname: req.body.surname,
firstname: req.body.firstname,
}
);
console.log('saving model');
newStud.save();
console.log('rendering model');
Models.Student.find({},
function(err,result){
console.log('finding results');
if (err) {
throw err;}
else {
console.log('returning results');
res.send(result);
}
}
);
},
When I update it with Fred's details, the console outputs the following:
creating model
saving model
rendering model
finding results
returning results
POST /students 200 21.629 ms - 5195
but the page only shows the following:
[
{
"surname": "Smith",
"firstname":"John"
"_id": "55bed36461521187445e5b53",
"__v": 0
},
{
"surname": "Peters",
"firstname":"Tom",
"_id": "55bed3f6c4faaa63464fc6df",
"__v": 0
},
]
I suspect my callback is not working properly. Can anyone explain why? Any help is most appreciated.

The problem here is of course that .save() is an asynchronous method in itself. So to need to wait for it to respond before asking for data from the collection. Otherwise, it likely has not actually created the new item yet:
create: function(req, res) {
console.log('creating model');
var newStud = new Models.Student({
surname: req.body.surname,
firstname: req.body.firstname,
}
);
console.log('saving model');
newStud.save(function(err,doc) { // <-- callback here
console.log('rendering model');
Models.Student.find({},
function(err,result){
if (err) {
throw err;}
else {
console.log('returning results');
res.send(result);
}
}
);
});
});
So basically you need to "wait" for the other .save() action to respond before you go query the whole collection to see the new addition.

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.

Mongoose find query gives results in wrong order

I am saving an updated array of _id's to an array on a document. If I check the document, everything is updating quite nicely, but when I populate right afterward using a new find query, it doesn't work right. populate wasn't working for me, so I decided to handle it manually and I am successful at filling them in, but they're in the wrong order.
export function sort_update(req, res) {
Action.findOneAndUpdate({
_id: req.query.action
}, {
child_actions: req.body.newArray
}, {
useFindAndModify: false, new: true
}, function(err, doc) {
if (err) return res.send(500, {
error: err
});
console.log("child action id strings after update", doc.child_actions); // ["1", "2"] correct!
Action.find({'_id': {$in: doc.child_actions }}, function(err, child_action_docs) {
if (err) return res.send(500, {
error: err
});
console.log("child action objects after fill", child_action_docs); // [{ _id: "2" }, { _id: "1" }] wrong!
doc.child_actions = child_action_docs;
res.send(doc);
});
});
}
Why are they in the wrong order? Does {'_id': {$in: doc.child_actions }} simply not guarantee any order at all? Do I have to re-sort my objects to the doc.child_actions order deliberately or is there a simpler way of telling mongodb to keep the order in the original array?

MongoDB: findOne returns null but document exists in collection

I'm trying to send an email and password server-side and check if a document with those values exists (which it does), but when I console log the results from the query it's null.
Here's the document in the users collection:
{
"_id" : ObjectId("580bcf9874ae28934705c0fc"),
"email" : "johndoe#gmail.com",
"password" : "pass"
}
Here's what I'm sending server-side:
{"email":"johndoe#gmail.com","password":"pass"}
Here's my code (updated):
mongo.connect('mongodb://localhost:27017', function (err, db) {
if (err) {
console.log("error: " + err); // logs nothing
} else {
var users = db.collection("users");
var tasks = db.collection("tasks");
app.post("/login", function(req, res) {
var emailRegex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var userInDb;
var userEmail = req.body.email;
var userPassword = req.body.password;
console.log(req.body.email); // logs "johndoe#gmail.com"
console.log(req.body.password); // logs "pass"
if (!userEmail || !userPassword) {
return res.sendStatus(403);
} else if ( !emailRegex.test(userEmail)) {
return res.sendStatus(403);
} else {
users.findOne( { "email": userEmail, "password": userPassword }, function(err, results) {
console.log(results); // logs "null"
if(err) {
console.log("error: " + err); // logs nothing
res.sendStatus(403);
} else {
console.log("here"); // logs "here"
res.sendStatus(200);
}
});
}
});
}
});
each time you pass a callback that has an error parameter, it's your responsibility to check if an error was passed, and if so, deal with it.
in your code, you have two such callbacks:
mongo.connect('mongodb://localhost:27017', function (err, db)
users.findOne( { "email": userEmail, "password": userPassword }, function(err, results)
either one of them can return an error object that might explain the issue.
add the following to the first line of each callback:
if (err) {
return console.log("error: " + err);
}
This one worked for me.
I had to call toArray() method.
I don't remember how I found that solution, cuz in MongoDB manuals they don't call to array method
users.findOne( { "email": userEmail, "password": userPassword }).toArray()
I faced a simular problem in one of my project. It is all because I stored the collection and the document in a database which is different from which my app is connected to. Check that once.
It is really mysterious, I think MongoDB client should make a fix on it.
MongoDB is not very reliable. Often get lose connection in 1/10 of requests. But the very annoying is, it returns an empty array instead of an error in connection, that makes us impossible to catch connection error.
Because I use the existence of documents in DB to reinitialize the project, I really get annoyed of it. CouchDB will not have this problem.
users.findOne({'email' : userEmail , 'password':userPassword }, function(err, result) {
console.log("result:"+result);
});

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

Remove element from array that is inside of another array in mongoose

The problem is that i can't remove an attachment from an object, in mongoose, with the next schema.
var question=mongoose.Schema({
_id:mongoose.Schema.Types.ObjectId
answers:[{
_id:mongoose.Schema.Types.ObjectId
attachments:[
_id:mongoose.Schema.Types.ObjectId
]
}]
});
I try to remove an attachment from a document with the next code.
Question.update({
_id: req.params.idQuestion,
'answers._id': req.params.idAnswer
}, {
$pull: {
'answers.$.attachments':{_id:req.params.idAttachment}
}
}, function (err, updated) {
if(err){
return res.status(400).send(err);
}
else if(!updated.nModified){
return res.status(400).send('Question hasn\t been updated.');
}
res.send(200);
});
I thought my query weren't correct and tried to do that in mongo shell. It worked perfectly.
db.questions.update({
_id:ObjectId('xx'),
'answers._id':ObjectId('yy')
},{
$pull:{
'answers.$.attachments':{_id:ObjectId('zz')}
}
})
Someone can help me with this problem?
Try this:
var qid=req.params.idQuestion,
aid=req.params.idAnswer;
//find
Question.find({
_id: qid,
'answers._id': aid
},{
answers:1
},function(err,question){
//change
var answers=question.answers.filter(function(el){
return el._id!=aid;
});
//update
Question.update({
_id: qid,
},{$set:{
answers:answers
}},function(err,updated){
...//your callback here
});
});

Resources