eozzy
eozzy

Reputation: 68650

Synchronous for loop

MongoClient.connect('mongodb://127.0.0.1:27017/manufacturers', 
  function(err, db) {
    db.listCollections().toArray(function(err, collections) {
      for (var key in collections) { // iterate over all collections
        var manufacturer = collections[key]['name'];
        var query = {}; // and get all documents
        findDocuments(db, manufacturer, query, processData);
      }
    });
  });

var findDocuments = function(db, collection, queryObj, callback) {
  var cursor = db.collection(collection).find(queryObj);
  cursor.each(function(err, docs) {
    if (docs != null) { console.log(docs); }
  });
}

.. it works but only gets data from one of the collections, not all.

It appears that for loop ends right away, how do I make it wait until the intermediate functions are returned?

Upvotes: 0

Views: 165

Answers (1)

endling
endling

Reputation: 84

For loops run synchronously, what you need is a function. I created a sample database with the following structure,

manufacturers (db)
  man1 (collection 1)
   man1doc1
   man1doc2
  man2 (collection 2)
   man2doc1

And ran the following code to print all documents in all collections sequentially, one collection at a time.

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

MongoClient.connect('mongodb://127.0.0.1:27017/manufacturers', 
function(err, db) {
db.listCollections().toArray(function(err, collections) {

  if(!collections.length){
    console.log('No collections found');
    return;
  }

  function sequentialIterate(key){
    if(key === collections.length){
      console.log('All documents in all collections printed');
      return;
    }
    var manufacturer = collections[key]['name'];
    var query = {};

    db.collection(manufacturer).find(query, function(err, cursor){
       cursor.each(function(err, doc){
        if(doc){
          console.log(doc);
        }
        else{
          console.log('All documents in collection ' + manufacturer + ' printed');
          sequentialIterate(key + 1);
        }
      });
    });       
  };

  sequentialIterate(0); // kick things off

 });
});

Prints out the following :

{ _id: 57cc44fc03b65f4084865057, name: 'man2doc1' }
All documents in collection man2 printed
{ _id: 57cc44f003b65f4084865055, name: 'man1doc1' }
{ _id: 57cc44f303b65f4084865056, name: 'man1doc2' }
All documents in collection man1 printed
All documents in all collections printed

You can replace the console.log() with callbacks if you want.

Upvotes: 1

Related Questions