charleslcso
charleslcso

Reputation: 182

Moving nodejs MongoDB connection code to another file

Moving the database connection code another nodejs file, no connection object is returned.

I can write data to MongoDB in nodejs. All db connection code is written in a single .js file.

Now I try to seperate the db connection code to another .js file, and now it seems that no connection can be made successfully.

Here is the working code in 1 .js file:

  const mongoDBIP = '192.168.1.71';
  const mongoDBPort = 27017;

  const mongo= require('mongodb').MongoClient;
  const mongoURL = 'mongodb://<mongo admin>:<password>@'+`${mongoDBIP}`+':'+`${mongoDBPort}`;

  ...

    mongo.connect(mongoURL, { useNewUrlParser: true, useUnifiedTopology: true }, (err, db) => {
    if (err) {}

    var dbo = db.db(<databaseName>);

    var collection = dbo.collection('messages');

    collection.insertOne(message, (err, result) => {
            if (err) {}
    })

  ...

Now I break this into 2 .js files:

  var _mongo = require('./mongodb.js');

  var mongoDBO = _mongo.mongoDBO;

  ...

    var dbo = mongoDBO('feathers');

    console.log('DBO:' + dbo);   <-- here, dbo is NULL

    var collection = dbo.collection('messages');

    collection.insertOne(message, (err, result) => {
            if (err) {}
    })

  ...

Here is the content of mongodb.js:

  // mongodb.js

  const mongoDBIP = '192.168.1.71';
  const mongoDBPort = 27017;

  const mongoClient = require('mongodb').MongoClient;
  const mongoURL = 'mongodb://<mongo admin>:<password>@'+`${mongoDBIP}`+':'+`${mongoDBPort}`;


  function mongoDBO(database) {

    var dbo;

    mongoClient.connect(mongoURL, { useNewUrlParser: true, useUnifiedTopology: true }, (err, dbase) => {
            if (err) {}
            dbo = dbase.db(database);   <-- here, dbo is NULL
    });

    return dbo;
  }

  module.exports = Object.freeze({
      mongoDBO
  });

I expect the object "dbo" in mongodb.js would not be NULL, but it is. This occurs under both nodejs v10.x and v12.x.

Upvotes: 0

Views: 2818

Answers (3)

SuleymanSah
SuleymanSah

Reputation: 17858

Here is an implementation what Tom explained, in case you need.

mongodb.js

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

const mongoDBIP = '192.168.1.71';
const mongoDBPort = 27017;

const mongoURL = 'mongodb://<mongo admin>:<password>@'+`${mongoDBIP}`+':'+`${mongoDBPort}`;

let _db;

const initDb = callback => {
  if (_db) {
    console.log('Db is already initialized!');
    return callback(null, _db);
  }
  mongoClient .connect(mongoURL)
    .then(client => {
      _db = client;
      callback(null, _db);
    })
    .catch(err => {
      callback(err);
    });
};

const getDb = () => {
  if (!_db) {
    throw Error('Db not initialized');
  }
  return _db;
};

module.exports = {
  initDb,
  getDb
};

Initialize it in your main file (index, app or server.js)

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


mongodb.initDb((err, mongodb ) => {
  if (err) {
    console.log(err);
  } else {
    app.listen(3000);
  }
});

And use it in your routes:

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


  mongodb.getDb()
    .db()
    .collection('your_collection_name')....

Upvotes: 2

Ankit Kumar Rajpoot
Ankit Kumar Rajpoot

Reputation: 5600

Try like this

const mongoDBIP = "192.168.1.71";
const mongoDBPort = 27017;
const mongoClient = require("mongodb").MongoClient;
const mongoURL =
  "mongodb://<mongo admin>:<password>@" +
  `${mongoDBIP}` +
  ":" +
  `${mongoDBPort}`;

var mongoDBO = database =>
  new Promise((resolve, reject) => {
    mongoClient.connect(
      mongoURL,
      { useNewUrlParser: true, useUnifiedTopology: true },
      (err, dbase) => {
        if (err) {
          reject(err);
        }
        resolve(dbase);
      }
    );
  });

module.exports = Object.freeze({
  mongoDBO
});

&

var _mongo = require('./mongodb.js');

var mongoDBO = _mongo.mongoDBO;

...

try {
    let dbo = mongoDBO('feathers');

    console.log('DBO:' + dbo);   <-- here, dbo is NULL

    var collection = dbo.collection('messages');

    collection.insertOne(message, (err, result) => {
            if (err) {}
    })
} catch (error) {
    console.log(connection failed)
}


...

Upvotes: 0

Tom Boutell
Tom Boutell

Reputation: 7572

You are trying to return a value that does not exist yet. dbo is not set until the callback function is invoked. The original function has already returned at that point.

You must alter your mongodb.js file to export a function that takes a callback, and passes dbo to that callback when it is ready.

I recommend reading up on callbacks and asynchronous programming.

Upvotes: 0

Related Questions