1

I'm trying to create a module that connects to my Database (couchDB using Cradle). In the end, the module exports the 'db' variable.

Here is the code:

var cradle = require('cradle'),
config = require('./config.js');

var db = new(cradle.Connection)(config.couchURL, config.couchPort, {
    auth: {
        username: config.couchUsername,
        password: config.couchPassword
    },
    cache: true,
    retries: 3,
    retryTimeout: 30 * 1000
}).database('goblin'); //database name



//Check if DB exists
db.exists(function (err, exists) {
    if (err && exists) {
        console.log("There has been an error finding your CouchDB. Please make sure you have it installed and properly pointed to in '/lib/config.js'.");
        console.log(err);
        process.exit();
    } else if (!exists) {
        db.create();
        console.log("Welcome! New database created.");
    } else {
        console.log("Talking to CouchDB at " + config.couchURL + " on port " + config.couchPort);
    }

});

module.exports = db;

The problem is that the db.exists call is async, and if it doesn't exist I think the variable exports the variable before it's done, effecting the rest of the system.

It's being included in the executed node page the normal way:

var db = require('./couchdb.js');

Is there a way to prevent this from happening, or any best practices to tackle a problem like this without having a giant nested callback?

For reference, you can see the entire application right here (https://github.com/maned/goblin) , and the bug referenced for the project here (https://github.com/maned/goblin/issues/36).

streetlight
  • 5,968
  • 13
  • 62
  • 101

1 Answers1

3

Embrace the async style. Instead of exporting db from the module, export an async function like this:

module.exports = {
  getDb: function(callback) {
    db.exists(function(err, exists) {
      if (exists && !err) {callback(db);} else { /* complain */ }
    });
  }
};

Now the application can just require('mymodule').getDb(appReady) where appReady accepts a db object that is known to be valid and usable.

wberry
  • 18,519
  • 8
  • 53
  • 85
  • This is a good solution! I am trying now but having some problems with the db object. Will keep this thread updated! I was trying intially to avoid having to nest callbacks like this (a lot of code goes into the callback) but maybe that's the best way to do it. – streetlight Dec 19 '13 at 13:12
  • You can "factor out" parts of your callback that never change into other functions or, if you're feeling froggy, into closures. That way only very tiny functions get dynamically created with each call to your event handler. – wberry Dec 19 '13 at 19:15