Persistent mongodb connection function? - node.js

How to manage mongodb connections in a nodejs webapp?
The answer of that question is superb. I would like code however to show this. I've tried the following but since it connects async the connection is not ready by the time I want to do my database query. I'm wondering how do others do this?
'use strict';
// database stuff
var mongodb = require('mongodb'); // mongodb drivers
var MongoClient = mongodb.MongoClient; // interface
var url = 'mongodb://127.0.0.1:27017/self';
// generator flow control
var co = require('co');
// database connect function
var dbConnect = function (url) {
// get the db object
MongoClient.connect(url, {
safe: true
}, function (err, db) {
if (err) throw err;
console.log('mongodb connection successful');
return db;
});
};
var db = dbConnect(url);
// generator function with flow control
co(function* () {
console.log('starting db query');
// count documents in collection
var result =
yield new Promise(function (resolve, reject) {
if (err) reject(err);
db.collection('test').count(function (err, res) {
if (err) reject(err);
resolve(res);
});
});
// output number of documents in collection
console.log(result);
});
// more code....
I would like to use the variable db anywhere in my app.

Here maybe one way to reuse the connection.
var myDb;
//reuse connection if already created
function connect(callback) {
if (myDb === undefined) {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) { return callback(err)};
myDb = db;
callback(null, db);
});
} else {
callback(null, myDb);
}
function doDBOperation(err, db) {
// your mongodb operation through db is here
co(function* () { ...
}
connect(doDBOperation);

You can wrap your database connection into promise and wait it in generator
function connect() {
return new Promise((resolve, reject) => {
MongoClient.connect(url, {safe: true}, (err, db) => {
if (err) return reject(err);
resolve(db);
});
});
}
var dbConnection = connect();
co(function* () {
var db = yield dbConnection;
// your code
});

Related

Why my function for retrieving data from mongodb is returning undefined?

I am trying to return all the entries from a mongodb collection from a nodejs.
I had written the function and it works if i console log the result i see all the objects from the colletion, but if i try to return the result i am getting undefined.
I cant figure it out why? I had also tried to JSON stringify and JSON parse after but still no success.
Here is my code:
`
const mongoUrl = "mongodb://192.168.8.156:27017/";
const getRoomReadings = function (id) {
MongoClient.connect(mongoUrl, function (err, db) {
if (err) throw err;
let dbo = db.db(`room${id}`);
dbo
.collection("env")
.find({})
.toArray(function (err, result) {
if (err) throw err;
return result;
});
});
};
// API RoomX route
app.get("/api/r:id", (req, res) => {
const rez = getRoomReadings(req.params.id);
console.log(rez);
});
`
I am using nodejs with express.
Please help me. Thanks in advance.
I had also tried to JSON stringify and JSON parse after but still no success.
I don't know why you created the connection each time you do the request but using promises will help you.
Example:
const mongoUrl = "mongodb://192.168.8.156:27017/";
const getRoomReadings = function (id) {
return new Promise((res, rej) => {
MongoClient.connect(mongoUrl, function (err, db) {
if (err) rej(err);
let dbo = db.db(`room${id}`);
dbo
.collection("env")
.find({})
.toArray(function (err, result) {
if (err) rej(err);
return res(result);
});
});
})
};
// API RoomX route
app.get("/api/r:id", async (req, res) => {
const rez = await getRoomReadings(req.params.id);
console.log(rez);
});
a better way to create a connection it creating a file call conn.js and inside that file create your connection
const { MongoClient } = require("mongodb");
const connectionString = process.env.ATLAS_URI;
const client = new MongoClient(connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
let dbConnection;
module.exports = {
connectToServer: function (callback) {
client.connect(function (err, db) {
if (err || !db) {
return callback(err);
}
dbConnection = db.db(<db_name>);
console.log("Successfully connected to MongoDB.");
return callback();
});
},
getDb: function () {
return dbConnection;
},
};
initialize the connection and use getDb to get the connection

Problems returning database information with MongoDB, Node.js and Express

const express = require('express');
const second = express();
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'myorders';
// Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
console.log("The connection was awesome");
const db = client.db(dbName);
second.get('/Students',(req,res) => {
const findStudents = function(db,call) {
const collection = db.collection('Students');
collection.find({}).toArray(function (err,result) {
if (!err) {
res.send(result)
} else {
console.log(err);
call(err);
}
});
}
});
client.close();
});
second.listen(3200,() => {
console.log('We got it running');
});
module.exports = second;
So I am trying to display my mongodb information on a web server and here are the screen shots
Above is the MongoDB collection of students and marks
And above is my Node.js command prompt and I get a deprecation warning. Is there any way I can fix it? Is there any other error why I can't display the information in the web server?
To fix this deprecation warning, all you need is to do what it says: pass the option useNewUrlParse: true in the options object to MongoClient.connect. So the line where you connect to MongoDB database would be:
MongoClient.connect(url, { useNewUrlParse: true }, function(err, client)
Anyway, this is just a warning, not a blocking error, and your app is running. I think there are several things wrong in your code, mainly that you declare the function to be executed on the GET to /Students within the callback of the connection to the database and that you close that connection so that the data could no longer be accessed. I think this code should work for you:
const express = require('express');
const second = express();
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const dbUrl = 'mongodb://localhost:27017';
const dbName = 'myorders';
let db;
MongoClient.connect(url, (err, client) => {
assert.equal(null, err);
db = client.db(dbName);
console.log("The connection was awesome");
});
second.listen(3200, () => {
console.log('We got it running');
});
second.get('/Students', (req, res) => {
db.collection('Students').find().toArray((err,result) => {
if (!err) {
res.send(result)
} else {
console.log(err);
res.status(500).send(err);
}
});
});
EDIT:
If you think that the database should not be always opened, yous should connect and close at each request to /Students, this way:
second.listen(3200, () => {
console.log('We got it running');
});
second.get('/Students', (req, res) => {
MongoClient.connect(url, (err, client) => {
if (err) return res.status(500).send(err);
db = client.db(dbName);
db.collection('Students').find().toArray((err,result) => {
if (!err) {
res.send(result)
} else {
console.log(err);
res.status(500).send(err);
}
client.close();
});
});
});

Mongo DB make connection outside of post?

I am using MongoDB to insert a record into the database, every time the post method is called. I know I do not want to connect to the db inside of the post function every time, but this is giving me errors? How can I correct this?
var mongo = require('mongodb');
var url = 'mongodb://localhost:27017/Wedding'
var db = function() {
mongo.connect(url, function(err, db){
if (!err){
return db;
}
});
}
app.post('/rsvp', function (req, res) {
var item ={
name: req.body.name,
attending: req.body.attending,
};
insertItem(item);
res.sendFile(path.join(__dirname + '/confirm.html'));
})
function insertItem(item){
db.collection('rsvpList').insertOne(item, function(err, result){
assert.equal(null, err);
})
}
I am getting this error:
TypeError: Object function () {
mongo.connect(url, function(err, db){
if (!err){
return db;
}
});
} has no method 'collection'
at insertItem (C:\Users\A587092\Documents\weddingWebsite\server.js:53:8)
at app.listen.host (C:\Users\A587092\Documents\weddingWebsite\server.js:38:4)
at Layer.handle [as handle_request] (C:\Users\A587092\Documents\weddingWebsite\node_modules\express\lib\router\layer.js:95:5)
The problem is your db does not point to the Mongo instance rather to a function!
Try this -
var mongo = require('mongodb');
var url = 'mongodb://localhost:27017/Wedding'
var db;
mongo.connect(url, function(err, connectedDB){
if (!err){
db = connectedDB;
}
});
You couldn't simply return a value from an asynchronous method:
You should use a callback function:
var connectDb = function(url, cb) {
mongo.connect(url, function(err, db){
if ( err ) {
cb( err );
}
cb(null, db);
});
};
Usage:
function insertItem(item) {
connectDb(url, function(error, db) {
if ( error ) {
throw error;
}
db.collection('rsvpList').insertOne(item, function(err, result) {
assert.equal(null, err);
});
});
}
Or a promise:
var connectDb = function(url) {
return new Promise(function(resolve, reject) {
mongo.connect(url, function(err, db){
if ( err ) {
reject(err);
}
resolve(db);
});
});
};
Usage:
function insertItem(item) {
connectDb(url)
.then(function(db) {
db.collection('rsvpList').insertOne(item, function(err, result) {
assert.equal(null, err);
});
}, function(err) {
throw err;
});
}
I change the function name from db to connectDb because we want to connect to db and then doing something after connecting. and this way your code reads well.
Also note that here also your insertItem function doing an asynchronous task so if you need the result outside of this function you should implement a similar approach, i leave it to you ;)

Cannot read property 'collection' of null

Here is my code
// Retrieve
var MongoClient = require('mongodb').MongoClient;
// Connect to the db
MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
if(!err) {
console.log('we are connected');
}
var k ='testt';
var collection = db.collection(k);
var doc1 = {'hello':'doc1'};
var doc2 = {'hello':'doc2'};
var lotsOfDocs = [{'hello':'doc3'}, {'hello':'doc4'}];
collection.insert(doc1);
collection.insert(doc2, {w:1}, function(err, result) {});
collection.insert(lotsOfDocs, {w:1}, function(err, result) {});
});
and it is is showing this error "Cannot read property 'collection' of null".
The issue is you are directly calling db.collection irrespective of whether db connection is successful or not. You need to check whether there is an error in db connection. db.collection works only when the DB connection is successful. Check below example for better understanding
MongoClient.connect('mongodb://localhost:27017/test',function(err,db){
if(err)
{
console.log(err);
}
else
{
console.log("Connected to db");
db.collection('testt').insert({"doc1":"hello"},function(err,data){
if(err)
{
throw(err);
}
else
{
console.log("sucessfuly inserted");
}
})

How to reference a connection to MongoDB in NodeJS [duplicate]

This question already has an answer here:
NodeJS Can't Access Variable Inside Callback
(1 answer)
Closed 7 years ago.
I have the following code:
var db;
MongoClient.connect("mongodb://localhost:27017/mobregserver", function(err, database) {
if(!err) {
console.log("We are connected");
}
db = database;
});
db.collection('bbr').insert({fields: "fields", files: "files"}, {upsert:true}, function(err, result) {
if(!err){
console.log("written");
}
});
And I get the following output:
We are connected
TypeError: Cannot call method 'collection' of undefined
var db;
MongoClient.connect("mongodb://localhost:27017/mobregserver", function(err, database) {
if(!err) {
console.log("We are connected");
db = database;
db.collection('bbr').insert({fields: "fields", files: "files"}, {upsert:true}, function(err, result) {
if(!err){
console.log("written");
}
});
}
});
Connect method is asyncrone, so your db variable will be initialized much later, then you start using it. Try this code:
MongoClient.connect("mongodb://localhost:27017/mobregserver", function(err, database) {
if(err) {
// Here, it may be better to interrupt further work in case of error
console.log('fail', err);
return;
}
var db = database;
db.collection('bbr').insert({fields: "fields", files: "files"}, {upsert:true}, function(err, result) {
if(!err){
console.log("written");
}
});
});
EDIT
A full example of nodejs server, taken from here
var express = require('express');
var mongodb = require('mongodb');
var app = express();
var MongoClient = require('mongodb').MongoClient;
var db;
// Initialize connection once
MongoClient.connect("mongodb://localhost:27017/integration_test", function(err, database) {
if(err) throw err;
db = database;
// Start the application after the database connection is ready
app.listen(3000);
console.log("Listening on port 3000");
});
// Reuse database object in request handlers
app.get("/", function(req, res) {
db.collection("replicaset_mongo_client_collection").find({}, function(err, docs) {
docs.each(function(err, doc) {
if(doc) {
console.log(doc);
}
else {
res.end();
}
});
});
});

Resources