7

Currently using node 4.3.2 and mongo 2.6. I am attempting to get a whole collection (three documents currently in the collection). When i use this bit of code i run into an issue.

function checkUpdateTime(last_updated){
    var collection = db.collection(last_updated);
    collection.insert({a:1});
    updateTimes = collection.find({a:1}).toArray();
}
var updateTimes = [];
checkUpdateTime('last_updated');
console.log(updateTimes);

When this code is tun updateTimes is a promise and not the array i was hoping for. The goal is the edit the array then insert it back into the collection later.The insert statement works but the retrieval of the documents simply doesn't operate the way i was expecting. I have tried quite a few versions of this code but no dice.

I guess it boils down to me wondering why a promise is being returned?

1 Answer 1

11

The MongoDB driver offers two options for handling asynchronous operations:

  • through callbacks that get passed by the caller
  • by returning a promise to the caller

When you don't pass a callback, like in your case, it will return a promise.

So you need to make a choice here. One choice that you can't choose is "make this code run synchronously", though.

I prefer promises:

function checkUpdateTime(last_updated){
  var collection = db.collection(last_updated);
  return collection.insert({ a : 1 }) // also async
                   .then(function() {
                     return collection.find({ a : 1 }).toArray();
                   });
}
checkUpdateTime('last_updated').then(function(updateTimes) {
  console.log(updateTimes);
});

You could always go a bit more fancy and use something like Promise.coroutine, that will make your code look a bit more synchronous (even though it isn't):

const Promise     = require('bluebird');
const MongoClient = require('mongodb').MongoClient;

let checkUpdateTime = Promise.coroutine(function* (db, last_updated){
  let collection = db.collection(last_updated);
  yield collection.insert({ a : 1 });
  return yield collection.find({ a : 1 }).toArray();
});

Promise.coroutine(function *() {
  let db = yield MongoClient.connect('mongodb://localhost/test');
  let updateTimes = yield checkUpdateTime(db, 'foobar');
  console.log(updateTimes);
})();

Or async/await, using Babel:

const MongoClient = require('mongodb').MongoClient;

async function checkUpdateTime(db, last_updated) {
  let collection = db.collection(last_updated);
  await collection.insert({ a : 1 });
  return await collection.find({ a : 1 }).toArray();
}

(async function() {
  let db = await MongoClient.connect('mongodb://localhost/test');
  let updateTimes = await checkUpdateTime(db, 'foobar');
  console.log(updateTimes);
})();
Sign up to request clarification or add additional context in comments.

2 Comments

"you can't choose". He can. With async/await.
@vp_arth still, that won't make it synchronous (the clue is in the name, "async" ;-). It may look like it, though, that's why I added it as an example :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.