Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How use Mongoose on inner npm module

How can I use a Mongoose already opened connection inside an npm module that resides in /node_modules?

For instance:

  • app
    • common
      • db.js
    • node_modules
      • a_module
        • models
          • a_model.js
        • index.js
    • app.js

app.js trigger opens a connection by requiring common/db.js and executing a connect() method.

Later in app.js a call is made to a_model/index.js where is required the a_model.js file and then is issued a findOne() call that never gets executed since it detects that no connection is open so the call is enqueued forever and never executes.

I already checked that the connection is already opened by checking the logs so the issue is other.

It's worth to note that I was able to get a similar setup working fine but instead of having a_module to be a npm module it was a regular directory below the app folder.

SOLUTION

Finally I got this working properly with the help of the awesome guys below.

By using the global nodejs object I was able to expose the db connection without clutter the code:

db.js:

global.db = mongoose;

a_model.js:

mongoose = global.db;

and voilá!

Reference: http://productbuilder.wordpress.com/2013/09/06/using-a-single-global-db-connection-in-node-js/

like image 763
Diosney Avatar asked Mar 21 '23 06:03

Diosney


2 Answers

Node caches calls to require so that you don't have to reinit the module on each require.

http://nodejs.org/docs/latest/api/modules.html#modules_caching

However, sub dependencies are not guaranteed to use the same object:

http://nodejs.org/docs/latest/api/modules.html#modules_module_caching_caveats

mongoose connections depend on this caching mechanism to keep an open connection to MongoDB. So in your case, when you moved a_module into its own module, you're essentially instantiating two mognoose objects and only your first mongoose object is opening a connection. The second object never opens a connection.

You can fix this by either having each module establish their own connection, or you'll have to go back to a_module not being an independent package.

like image 86
srquinn Avatar answered Apr 01 '23 16:04

srquinn


option 1:

// app.js
var mongoose = require('mongoose');
var db = require('db')(mongoose);
var a_module = require('a_module')(mongoose);

option 2:

re-check package.json for each modules. Make sure they are resolvable to a single version of mongoose.

BAD DEPENDENCIES:
app.js need  {"mongoose": "3.8"}
a_module need {"mongoose": "3.7"}
=> npm install will download 2 separated version of mongoose. 

GOOD DEPENDENCIES:
app.js need {"mongoose": ">= 3.8"}
a_module need {"mongoose": ">= 3.7"}
=> npm install will download 1 mongoose version for all app and a_module
like image 24
damphat Avatar answered Apr 01 '23 16:04

damphat