2012-08-07 12 views
5

Ecco una piccola storia.node-mongodb-native, callback, scope e TypeError

C'era una volta, un piccolo progetto voleva usare node-mongodb-native. Tuttavia, era molto timido e voleva usare un oggetto wrapper per nascondersi dietro di esso.

var mongodb = require('mongodb'), 
    Server = mongodb.Server, 
    Db = mongodb.Db, 
    database; 

var MongoModule = {}; 

MongoModule.setup = function() { 
    // Create a mongodb client object 
    var client = new Db(this.config.databaseName, 
     new Server(
      this.config.serverConfig.address, 
      this.config.serverConfig.port, 
      this.config.serverConfig.options 
     ), 
     this.config.options 
    ); 

    // Open the connection! 
    client.open(function(err, db) { 
     if (err) throw err; 
     database = db; 
     console.log('Database driver loaded.'); 
    }); 
}; 

Il metodo setup è stato un modo per ottenere il piccolo progetto è iniziato. Veniva chiamato quando l'applicazione era in esecuzione.

Per provare un po ', il piccolo progetto ha aggiunto un metodo wrapper per il metodo collection di node-mongodb-native.

MongoModule.collection = function() { 
    database.collection.apply(this, arguments); 
}; 

Ma poi, il piccolo progetto ha scoperto che questo metodo non ha funzionato. Non ha capito perché!

// In the client.open callback: 
db.collection('pages', function(e, p) { 
    // no error, works fine 
}); 

// in the same callback: 
MongoModule.collection('pages', function(e, p) { 
    // error :(
}); 

L'errore era il seguente, anche se il piccolo progetto non pensa che sia correlato. Il suo migliore amico Google non ha rivelato alcun risultato utile ma un vecchio bug fisso.

TypeError: Cannot read property 'readPreference' of undefined 
    at new Collection (/home/vagrant/tartempion/node_modules/mongodb/lib/mongodb/collection.js:56:92) 
    at Object.Db.collection (/home/vagrant/tartempion/node_modules/mongodb/lib/mongodb/db.js:451:24) 
    at Object.MongoModule.collection (/home/vagrant/tartempion/core/databases/mongodb.js:27:25) 
    at proxy [as collection] (/home/vagrant/tartempion/node_modules/ncore/lib/core.js:116:51) 
    at Object.module.exports.getIndex (/home/vagrant/tartempion/pies/page/model.js:4:17) 
    at proxy [as getIndex] (/home/vagrant/tartempion/node_modules/ncore/lib/core.js:116:51) 
    at Object.module.exports.index (/home/vagrant/tartempion/pies/page/controller.js:7:20) 
    at callbacks (/home/vagrant/tartempion/node_modules/express/lib/router/index.js:272:11) 
    at param (/home/vagrant/tartempion/node_modules/express/lib/router/index.js:246:11) 
    at pass (/home/vagrant/tartempion/node_modules/express/lib/router/index.js:253:5) 

PS: se volete un file in mancanza, here is a gist.

risposta

3

È necessario applicare il metodo collection nel contesto dell'oggetto database piuttosto che l'oggetto MongoModule:

database.collection.apply(database, arguments); 
+0

Wow. Come potrei essere così stupido. Grazie! –

+0

È così facile trascurare questo genere di cose. – scttnlsn