Check if mongoDB is connected - node.js

I have mongoDB in my app.
I want to check if mongoDB is connected, before I listen to the app.
Is it the best way for doing it?
This is my server.js file:
var express = require('express');
var mongoDb = require('./mongoDb');
var app = express();
init();
function init() {
if (mongoDb.isConnected()) {
app.listen(8080, '127.0.0.1');
}
else {
console.log('error');
}
}
isConnected runs getDbObject.
getDbObject connects to mongoDB and returns an object:
connected (true/false), db (dbObject or error).
Then, isConnected resolve/reject by connected property.
This is mongoDb.js file:
//lets require/import the mongodb native drivers.
var mongodb = require('mongodb');
// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost:27017/myDb';
var connectingDb; // promise
//We need to work with "MongoClient" interface in order to connect to a mongodb server.
var MongoClient = mongodb.MongoClient;
init();
module.exports = {
isConnected: isConnected
}
// Use connect method to connect to the Server
function init() {
connectingDb = new Promise(
function (resolve, reject) {
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
reject(err);
}
else {
console.log('Connection established to', url);
//Close connection
//db.close();
resolve(db);
}
});
}
);
}
function getDbObject() {
return connectingDb().then(myDb => {
return {
connected: true,
db: myDb
}
}
)
.catch(err => {
return {
connected: false,
db: err
}
}
)
}
function isConnected() {
return new Promise(
function(resolve, reject) {
var obj = getDbObject();
if (obj.connected == true) {
console.log('success');
resolve(true);
}
else {
console.log('error');
reject(false);
}
}
)
}
Any help appreciated!

there are multiple ways depends on how your DB is configured. for a standalone (single) instance. You can use something like this
Db.connect(configuration.url(), function(err, db) {
assert.equal(null, err);
if you have a shared environment with config servers and multiple shards you can use
db.serverConfig.isConnected()

Let client be the object returned from MongoClient.connect:
let MongoClient = require('mongodb').MongoClient
let client = await MongoClient.connect(url ...
...
This is how i check my connection status:
function isConnected() {
return !!client && !!client.topology && client.topology.isConnected()
}
This works for version 3.1.1 of the driver.
Found it here.

From version 3.1 MongoClient class has isConnected method. See on https://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html#isConnected
Example:
const mongoClient = new MongoClient(MONGO_URL);
async function init() {
console.log(mongoClient.isConnected()); // false
await mongoClient.connect();
console.log(mongoClient.isConnected()); // true
}
init();

There has been some changes since version 3, isConnected is no longer available in version 4. The correct way of dealing with an ambiguous connection is to just call MongoClient.connect() again. If you're already connected nothing will happen, it is a NOOP or no-operation, and if there is not already a connection you'll be connected (as expected). That said, if you really want to know if you have a connection try something like this:
const isConnected = async (db) => {
if (!db) {
return false;
}
let res;
try {
res = await db.admin().ping();
} catch (err) {
return false;
}
return Object.prototype.hasOwnProperty.call(res, 'ok') && res.ok === 1;
};

Related

Connect and disconnect from mongodb with mongoose

I'm trying to connect to my db for each time I make a CRUD action, and then disconnect. When I connecting at the first time it's working fine, but when I try to connect again it's not working, and making the disconnect function insted.
i tryed to remove the if cheking but it's still happaning.
what am i doing wrong?
database:
import Mongoose from 'mongoose';
let database: Mongoose.Connection;
export async function connect() {
const uri = 'mongodb://localhost:27017/storage';
if (database) { //problem here
return;
}
Mongoose.connect(uri);
database = Mongoose.connection;
database.once('open', async () => {
console.log('Connected to database successfully');
});
database.on('error', () => {
console.log(`Error connecting to database. Check Whether mongoDB
installed or you can try to give opensource Mongo Atlas database`);
});
return database;
};
export async function disconnect() {
if (!database) {
return;
}
Mongoose.disconnect();
console.log('Disconnected Successfuly')
};
controller:
async function create(req: Request, res: Response) {
const data = req.query;
const notValid = validateQueryParams(Object(data))
if (notValid) {
res.send(notValid)
} else {
try {
await connect();
await addTodb(data)
res.send('create')
} catch (err) {
res.send('Error creating')
} finally {
await disconnect();
}
}
}

how to decouple mongodb atlas connection from the express server start

Im trying to decouple my express server start from the mongodb connection process .
mongodb.connect(process.env.CONNECTIONSTRING, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
if (err) {
throw new Error(err)
}
module.exports = client
const server = require("./server")
server.start(opts, t => {
console.log(`server is up 4000`)
})
})
so instead of this single file I would like to have two files one used for mongodb connection , and other for starting the server . when i did this I got error related to mongodb, I think because the server started even before the mongodb conection was established.
any idea on how to solve this
Wrap it in a promise and call it wherever you want
Create a file name db.js it whatever else you want and require in the file that you need it. Then wrap the callback in a promise and export it for usage outside the file. Example above.
function initMongo() {
mongodb.connect(process.env.CONNECTIONSTRING, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, client) {
return new Promise((resolve, reject) => {
if (err) {
return reject(err);
}
return resolve(client)
})
})
}
module.exports = { initMongo };
Then in your init function, you could call
const server = require("./server");
const mongoDb = require("./db");
async init() {
let client;
try {
client = await mongoDb.initMongo()
} catch(e) {
// could not connect to db
}
server.start(opts, t => {
console.log(`server is up 4000`)
})
}

MongoDB-Express: Cannot get the client/db out of connect function

I am separating the connect function of MongoDB to a separate module, so that the mongoDB connection is reusable. The issue is, I could not get the client/DB variable outside the connect function. It shows undefined.
var MongoClient = require('mongodb').MongoClient;
var _client;
var mongoURL = "mongodb://localhost:27017/";
module.exports = {
connectToMongoServer: (callback) => {
MongoClient.connect(mongoURL,{ useNewUrlParser: true },function(err,client){
_client = client;
return callback(err);
});
},
getClient: () => {
return _client;
}
};
Within the connect function, the _client details contains the information, but if I return it using getClient, it shows undefined.
MongoDB - v3.6.5
Node - v9.9.0
I've made up a snippet which should work the same ad your code, and it works.
So I think the problem is how you are calling your function getClient(); are you sure you are calling it after it get connected?
var _client;
function someAsyncFunc(callback) {
setTimeout(() => callback(false, 'client'), 500);
}
const file = {
connectToMongoServer: (callback) => {
someAsyncFunc(function(err, client) {
_client = client;
return callback(err);
});
},
getClient: () => {
return _client;
}
};
console.log('display one :', file.getClient());
file.connectToMongoServer((err) => {
console.log('display error :', err);
console.log('display two :', file.getClient());
});

In node pg client.query doesn't return

I am currently updating a very old application to run on Heroku. I've had to update to the latest version of pg to support the latest postgres on heroku. However, this was originally abstracted out so it's all handled in the one file (below). I can connect to the DB successfully but client.query never returns.
The first console.log is SELECT * FROM public.user WHERE "email" = $1 [ 'xx#xx.com' ]. However, I never reach the second console.log. I get no connection errors.
I am using pg 7.x and postgres 10.
Any ideas?
const { Client } = require('pg');
const config = require('.././app/models/config.js');
const client = new Client({
connectionString: process.env.DATABASE_URL || config.database || ''
});
var conString = config.database || '';
client.connect();
module.exports = {
query: function(text, values, cb) {
console.log(text, values);
client.query(text, values, function(err, result) {
console.log(err, result);
if (err) {
console.log(err);
}
if (cb) {
cb(err, result);
}
client.end();
});
}
};
EDIT: I've edit with the correct promise from pg. Due the asynchronous nature of Nodejs you have to work with promises, something like:
module.exports = {
query: function(text, values) {
console.log(text, values);
return new Promise(function (resolve, reject) {
client.query(text, values)
.then(function (res) { resolve(res.rows[0]) })
.catch(function (e) { reject(e.stack) };
});
}
};
Then require you module and consume the promise:
var myPrevModule = require('module');
myPrevModule.query.then(function(resp){
// Consume the callback here ...
}).catch(function(err){
console.error(err);
})

error connecting to mongodb on Nodejs

I am trying to connect to mongodb from node and I am getting below error
node_modules\mongodb\lib\mongo_client.js:458
throw err
^
ReferenceError: connect is not defined
I am using the mongodb module version
2.0.48
I am trying to run a simple test code
(function (dbase) {
var mdb = require('mongodb');
var mongoUrl = "mongodb://localhost:27017/theBoard";
var connection;
dbase.dbConnection = function (next) {
if (connection) {
next(null, connection);
} else {
mdb.MongoClient.connect(mongoUrl, function(err, db) {
if (err) {
next(err, null);
} else {
console.log("connected");
connection = { db: db , notes: db.collection("notes")};
next(null, connection);
}
});
}
}
Can someone please help me understand this issue.
---Additional information
data module -
(function (data) {
var mdb = require('./db.js');
data.GetCategory = function() {
mdb.dbConnection(function(err, db) {
if (err)
console.log("Error connecting to mango");
if (connect) {
db.notes.count(function(err, count) {
if (err)
console.log("Failed to retreive collection");
else
console.log("Count - "+count);
});
console.log("Connected");
}
});
}})(module.exports);
db.js
(function (dbase) {
var mdb = require('mongodb');
var mongoUrl = "mongodb://localhost:27017/theBoard";
var connection;
dbase.dbConnection = function (next) {
if (connection) {
next(null, connection);
} else {
mdb.MongoClient.connect(mongoUrl, function(err, db) {
if (err) {
next(err, null);
} else {
console.log("connected");
connection = { db: db , notes: db.collection("notes") };
next(null, connection);
}
});
}
} })(module.exports);
Controller -
(function (controller) {
var data = require('.././data');
controller.init = function (app) {
app.get("/", handleRequest);
}
var handleRequest = function (req, res) {
data.GetCategory();
var a = {};
a.send = "Mamma is coming home";
res.send(a);
}
})(module.exports);
Just in case some one runs into an issue like this due to bad coding practice even if it for test purpose is to never have function names which are the same as the function names in the API. In db.js I had an undefined variable named connect which trowing and error when it was accessed and since it was called through the API function called "connect" the error was thrown by the API leading me to believe that the API function had an issue

Resources