mongodb async issue NodeJS - node.js

I'm using mongodb for a while and had countered this same issue many times.. like so:
XCollection.find({})
.each(function (err, x) {
if (err) throw err;
branchCollection.findOne(
{_id: new ObjectID(x.branchId)}
, function(err, doc){
console.log(x.branchId);
});
.....
and I see sometimes that findOne not working very well, x document changes because of the upper each, and that's affecting my code! I recognize that the problem is because those requests (db requests) is async. but what the recommended method to deal with this issue?
Thanks,
Best Regards

You do not need to use new ObjectID to query the ID field. A string will suffice.
branchCollection.findOne(
{_id: x.branchId}
, function(err, doc){
console.log(doc._id);
});
On another note, you should not be using the x variable in your async call. You should use:
console.log(doc._id)
Other than that, I'm not sure I understand what your question is? Are you receiving an error?

Related

Is there a (built-in) way to reverse a previously executed mongoose query?

I was wondering if there was an easy way to reverse a previously executed mongoose query, or whether I'd have to go the route of creating a way myself - all of my searching seems to suggest the latter.
To clarify, I'm hoping that I could do something like:
schema.create(data, (err, docs) => {
if(err) return err;
return docs;
});
And then call some sort of reverse helper function, like:
schema.reverse(0, (err, docs) => {
if(err) return reject(err);
resolve(docs);
});
Where the first argument to the function is an index into a history of some kind? Of course this is just hypothetical: if anything similar exists, or if you've implemented something like it before, then I'd love to know about it.
Thanks!

Converting object returned by MongoDB into bar?

I think this is a very simple question? I am a beginner trying to learn mongo with node.
Once I have saved something to a collection, how can I pull it out in simple var format?
db.highschools.save({
hsid :10,
name :"Johnson High School",
location:"San Diego, CA"
});
I simply want to store a var as 'Johnson High School'.
My failed attempts that have returned undefined are as follows...
var hsName = db.highschools.find({hsid:10}).name;
var hsName = db.highschools.find({hsid:10}).name.str;
Pretty sure I'm missing the big picture here, would someone please be kind enough to help me figure this out?
Use findOne instead:
var hsName = db.highschools.findOne({hsid:10}).name;
Also, note that this is a Mongo script, not a NodeJS script.
You'll need to make it async when you write the logic in NodeJS.
db.collection('students', function(err, collection) {
collection.findOne({hsid:10}, function(err, student) {
if (err) { throw err; }
console.log(student.name);
});
});
If you're confident that there should be only one result, then you can use the shortcut method findOne which simply calls find internally with a limit of one. If you were to use find, it returns an array of matches.

MongoDB on Node.js doesn't work, it returns undefined

In the following code:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/db_name', function(err, db){
if (err) throw err;
var collection = db.collection('col_name');
console.log(collection.find().toArray(function(err, items){}));
});
When I run the above, it doesn't return any results and instead returns undefined. What am I missing?
Also, in order to confirm there exist some collections on the db, which there are, I tried to add console.log(db.getCollectionNames());, but it looks like it has no such method in Node.js driver. So is it still possible to confirm the existence of collections? (Anyway I just want to use it as debug in these situations - usually I don't need the method though).
Thanks.
Don't log your entire find() function, do the checking in the callback:
collection.find().toArray(function(err, items){
console.log(items);
});
For the getCollectionNames() part, the method is actually called collectionNames() in the mongodb native driver :
db.collectionNames(function (err, list) {console.log(list)});

Node.js and MongoDB using Mongoose. Using findByIdAndUpdate vs Manual

are there any drawbacks to using findByIdAndUpdate and doing it manually. I noticed that findByIdAndUpdate drops my mongo connection, and read that you should try to keep connection open, only close when you close your app. Is this the case, and if so, is there a config setting that I am not seeing for findByIdAndUpdate, that keep the connection on?
updateItemById: function(id, updateObj, options, callback){
//OPTION 1
Badge.findById(id, null , function(err, doc){
doc.update(updateObj, function(err, numberAffected, raw){
if (err) return handleError(err);
Badge.findById(id, null , function(err, doc){
callback(doc);
});
});
});
//OPTION 2
Badge.findByIdAndUpdate(id, updateObj, options, function(err, data){
callback(doc);
});
}
findByIdAndUpdate should be faster (as long as the driver and mongoose are correctly programmed), because:
With Option 1:
Fetch the object by ID
Transform it into JavaScript object
Update object in client
Send back to DB
Calculate and save changes
Send it back
Transform into JavaScript object
With Option 2:
Find document in Database
Calculate and apply changes as atomic operation
Send object back
Transform into JavaScript object
As you can see, the second options does require less steps and therefore should be faster.
Bonus: The code is more readable.

NodeJS getting and passing variables

I am having some trouble figuring out variables "passing" (I know it's not the right term, I'll explain), given the asynchronous nature of node.js.
Please have a look at the following:
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if(err) {
throw err;
}
var solution = rows[0].solution;
});
res.render('index', { title: solution });
As you can imagine, I am getting a reference error, solution is not defined.
This is because the res.render is done before getting the solution from the mysql server.
How can I make it render the page once the solution is defined? I know it's something really little and stupid and is really at the very core of node, but please help me understand.
The second parameter of the connection.query is your callback which gets run after the database returns. Why not put the res.render line inside the callback? That way the render function isn't called until you have your data ready.
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if(err) throw err;
var solution = rows[0].solution;
res.render('index', { title: solution });
});
Callbacks can be a little tricky when you're first getting started with Node. You just have to think out the steps that need to happen and which are async. From there you just need to make sure your callbacks allow the process to continue.

Resources