0

I keep getting an error in regards to querying MongoDB:

var MongoClient = require('mongodb').MongoClient;
//assert = require('assert');


// Connection URL 
var url = 'mongodb://localhost:27017/myproject';
// Use connect method to connect to the Server 
 MongoClient.connect(url, function(err, db) {
//assert.equal(null, err);
if(err)
 throw err;
else{
console.log("Connected correctly to server");
var cursor = db.collection('documents').find({'_id':'01'});
cursor.forEach(function(err,doc) {
  if(err){
      throw err;
  } else{
      console.log(doc);
 }});
db.close();

}});

The error I am getting is this.

process.nextTick(function(){ throw err;});

[object Object]

Any help is appreciated! Thanks.

Ong Kong Tat
  • 1,172
  • 2
  • 9
  • 22
  • this is not an error. You are logging an object! – e4c5 May 11 '17 at 04:05
  • @e4c5 Wanted to clarify what you meant by logging an object. I do know what it means by object but not sure what logging an object mean. Thanks for your response as well. – Ong Kong Tat May 11 '17 at 06:09
  • like ` console.log(doc);` – e4c5 May 11 '17 at 06:39
  • @e4c5 Oh I see. If i want to query multiple items, what should I do instead of logging an object? – Ong Kong Tat May 11 '17 at 06:47
  • You can use a proper debugger. But the whole point is that you don't actually have an error here and this question doesn't make sense – e4c5 May 11 '17 at 06:48
  • Basically I am trying to query my item and after doing the query I am not getting the result that is meant to be there.Which is my question as to what did I do wrong to cause it to not be able to not query and output the result. Forgive me if I was unclear in my question. @e4c5 – Ong Kong Tat May 11 '17 at 07:55
  • `cursor.foreach` is async so you're calling `db.close();` before you've iterated over the cursor. – JohnnyHK May 11 '17 at 13:28
  • @JohnnyHK forEach is blocking, its not async – Samip Suwal May 11 '17 at 22:46
  • 1
    @SamipSuwal No, [`Cursor.forEach`](http://mongodb.github.io/node-mongodb-native/2.0/api/Cursor.html#forEach) is async because it's actually fetching the document from the server as the cursor is iterated. – JohnnyHK May 12 '17 at 02:26
  • @OngKongTat Because you're querying by `_id`, you should be using `findOne` instead, which eliminates having to deal with the cursor. – JohnnyHK May 12 '17 at 02:38
  • @JohnnyHK Do you mean that I should not declare cursor and forEach and just use findOne ? I do know how to use findOne in MongoDB just not sure how to use it in MongoDB through node.js. – Ong Kong Tat May 12 '17 at 02:44
  • @JohnnyHK yup you are right. upvoted your comment thanks. – Samip Suwal May 12 '17 at 03:07

2 Answers2

0

Hi if you use nextObject() instead of forEach, your code should do what you want.

            var MongoClient = require('mongodb').MongoClient;
    //assert = require('assert');
    // Connection URL 
    var url = 'mongodb://localhost:27017/myproject';
    // Use connect method to connect to the Server 
    MongoClient.connect(url, function(err, db) {
    //assert.equal(null, err);
    if(err)
    throw err;
    else{
    console.log("Connected correctly to server");
    var cursor = db.collection('documents').find({'_id':'01'});
    //CHANGE HERE
    //cursor.forEach(function(err,doc) {
    cursor.nextObject(function(err,doc) {
    if(err){
        throw err;
    } else{
        console.log(doc);
    }});
    db.close();

    }});  

UPDATE:

when you do forEach on cursor the callback gives you document as the first parameter. So your if was catching it and throwing it. That is why you are seeing that error to begin with. This is because the way node-mongodb-native driver behaves check this How can I use a cursor.forEach() in MongoDB using Node.js?

nextObject function will give you two parameters, error as the first and the doc as the second. https://mongodb.github.io/node-mongodb-native/api-generated/cursor.html#nextobject

Community
  • 1
  • 1
Samip Suwal
  • 1,253
  • 11
  • 17
0

Your code isn't working because you're not providing the right callback(s) to cursor.forEach and because that method is async so that you're calling db.close() before you've actually fetched your docs.

However, because you're querying for a single doc, you can use findOne instead which eliminates the complexity of dealing with the cursor returned by find:

MongoClient.connect(url, function(err, db) {
  if(err)
    throw err;
  else {
    console.log("Connected correctly to server");
    db.collection('documents').findOne({'_id':'01'}, function(err, doc) {
      if(err){
        throw err;
      } else{
        console.log(doc);
      }
      db.close();
    });
  }
});
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Thanks it really helped out in the sense that it is much simpler if I wanted to search for one document. Just wanted to clarify something, why did you put `db.collection('documents').findOne({'_id':'01'}, function(err,doc)` the query then comma instead of semicolon ? – Ong Kong Tat May 12 '17 at 03:30
  • Because `findOne` takes a callback as a second parameter. – JohnnyHK May 12 '17 at 03:33
  • Do you mean to say that you are calling back the function to execute? Sorry I am not too sure in terms of callback function. – Ong Kong Tat May 12 '17 at 03:36
  • `findOne` calls the callback function you provide as the second parameter to asynchronously deliver the found document to you. – JohnnyHK May 12 '17 at 03:38