Could not get mongodb connectivity with nodejs - node.js

I have tried this in nodejs but i am getting undefined as output in my console
// Connect using a MongoClient instance
const MongoClient = require("mongodb").MongoClient;
const test = require("assert");
// Connection url
const url = "mongodb://localhost:27017";
// Database Name
const dbName = "test";
// Connect using MongoClient
const mongoClient = new MongoClient(url);
mongoClient.connect(function (err, client) {
const db = client.db(dbName);
try {
db.collection("employeeDetails")
.find({})
.toArray(function (err, res) {
console.log(res);
});
} catch (e) {
console.log(e);
} finally {
client.close();
}
});
I have data in mongodb :
How do i get my employee details in my console Any help would be appreciated

You're closing the connection before getting the results. If you print err inside toArray() along with result, you will see below error -
MongoExpiredSessionError: Cannot use a session that has ended
This is happening because the db.collection("employeeDetails")... is getting called but waits for results in callback, till then it moves ahead and since after that statement you are exiting try-catch, you enter into finally which closes the session. When the db.collection... call is processed, this session is already ended and you see this error.
You can use async await. Modify your code as below -
// Connect using a MongoClient instance
const MongoClient = require("mongodb").MongoClient;
const test = require("assert");
// Connection url
const url = "mongodb://localhost:27017";
// Database Name
const dbName = "test";
// Connect using MongoClient
const mongoClient = new MongoClient(url);
mongoClient.connect(async function (err, client) {
const db = client.db(dbName);
try {
const result = await db.collection('employeeDetails').find({}).toArray();
console.log(result);
} catch (e) {
console.log(e);
} finally {
client.close();
}
});
In the line mongoClient.connect(async function (err, client).. we're using async before the callback function and later inside, we can just get the result using -
const result = await db.collection('employeeDetails').find({}).toArray();
After this console.log will print your results correctly.

This works for me
let result = await collection(collection).find(query).toArray()

Related

Mongodb native connections from nodejs return undefined databases list

I'm just starting to use Mongodb without mongoose (to get away from the schemas), and wanted to create a simple module with various exported functions to use in the rest of my app. I've pasted the code below.
The problem I'm having is that the databasesList.databases comes back as undefined, and I'm not sure why. There should be 2 databases on my cluster, and one collection in each database.
As a tangential question, I thought maybe I would check the collections instead (now commented out), but though I found this page (https://docs.mongodb.com/manual/reference/method/db.getCollectionNames/) the function getCollectionNames seems not to exist. Now I'm wondering if I'm using the wrong documentation and that is why my databases are coming back undefined.
const client = new MongoClient(uri)
const connection = client.connect( function (err, database) {
if (err) throw err;
else if (!database) console.log('Unknown error connecting to database');
else {
console.log('Connected to MongoDB database server');
}
});
module.exports = {
getDatabaseList: function() {
console.log('start ' + client);
databasesList = client.db().admin().listDatabases();
//collectionList = client.db().getCollectionNames();
//console.log("Collections: " + collectionList);
console.log("Databases: " + databasesList.databases);
//databasesList.databases.forEach(db => console.log(` - ${db.name}`));
}
}```
your code is correct Just need to change few things.
module.exports = {
getDatabaseList: async function() {
console.log('start ' + client);
databasesList = await client.db().admin().listDatabases();
//collectionList = await client.db().getCollectionNames();
//console.log("Collections: " + collectionList);
console.log("Databases: " + databasesList.databases);
databasesList.databases.forEach(db => console.log(` - ${db.name}`));
}
}
You have to declare async function and use await also.
The async and await keywords enable asynchronous, promise-based behaviour to be written in a cleaner style, avoiding the need to explicitly configure promise chains.
You can use this modular approach to build your database access code:
index.js: Run your database application code, like list database names, collection names and read from a collection.
const connect = require('./database');
const dbFunctions = require('./dbFunctions');
const start = async function() {
const connection = await connect();
console.log('Connected...');
const dbNames = await dbFunctions.getDbNames(connection);
console.log(await dbNames.databases.map(e => e.name));
const colls = await dbFunctions.getCollNames(connection, 'test');
console.log(await colls.map(e => e.name));
console.log(await dbFunctions.getDocs(connection, 'test', 'test'));
};
start();
database.js:: Create a connection object. This connection is used for all your database access code. In general, a single connection creates a connection pool and this can be used throughout a small application
const { MongoClient } = require('mongodb');
const url = 'mongodb://localhost:27017/';
const opts = { useUnifiedTopology: true };
async function connect() {
console.log('Connecting to db server...');
return await MongoClient.connect(url, opts );
}
module.exports = connect;
dbFunctions.js:: Various functions to access database details, collection details and query a specific collection.
module.exports = {
// return list of database names
getDbNames: async function(conn) {
return await conn.db().admin().listDatabases( { nameOnly: true } );
},
// return collections list as an array for a given database
getCollNames: async function(conn, db) {
return await conn.db(db).listCollections().toArray();
},
// return documents as an array for a given database and collection
getDocs: async function(conn, db, coll) {
return await conn.db(db).collection(coll).find().toArray();
}
}

Need help connecting and inserting data to mongodb

I need some help with mongodb.
I just started using it, and made a Cluster called db, with a database called discord-bot with a collection called users
This should make a database entry for every user, so here is my code
const { MongoClient } = require("mongodb");
const uri = "mongodb+srv://<My username>:<My password>#<My db url>?retryWrites=true&w=majority";
const client = new MongoClient(uri);
async function run(query) {
try {
await client.connect();
const database = client.db('discord-bot');
const collection = database.collection('users');
await collection.insertOne(query);
} finally {
await client.close();
}
}
botClient.users.cache.forEach(u => {
const q = { name: u.username }
run(q).catch(console.dir);
})
I think this code should work, but it is giving me this error
TypeError: Cannot read property 'maxWireVersion' of null
I can not find anything online about that error, can somebody help me figure out what that error is and how to fix it. (Also, i am using mongodb with discord.js, incase that is neccessary info)
I use this to connect to mongo DB
const MongoClient = require('mongodb').MongoClient;
var connection;
MongoClient.connect('your-db-uri', { useUnifiedTopology: true }, async function(err, client) {
if(err)throw err
console.log("Successfully Connected")
connection = client
})
Then you can use connection variable as global for all functions

uable to connect to mongdb Atlas from nodejs using mongoose

This is the error I am getting . please help to resolve this
Code
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://userName:password#saichaitanyacluster-1m22k.mongodb.net/test?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
const collection = client.db("test").collection("devices");
client.close();
});
You should add a check to confirm that there is no error in connection before calling client.db(). The connection code should be something like this:
// ...Everything that was here before
client.connect(err => {
if (err) {
console.log("There was an error connecting to the database");
// Any other logic that you want to use to handle the error should live here.
// Add a return statement to help avoid executing
// the code below that relies on a successful connection
return;
}
const collection = client.db("test").collection("devices");
client.close();
});
I hope this helps.

Unable to retrieve data from MongoDB in Express

I am trying to write a simple code to fetch some data from MongoDB in express.
Below is my code:
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/mcart'
MongoClient.connect(url)
.then(function (db) {
console.log(db)
})
.catch(function (err) {})
This gives me a JSON. But, when I try to access data from it, I get an error "db.collection" is not a function
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/mcart'
MongoClient.connect(url)
.then(function (db) {
var cursor=db.collection("product_catalog").find();
cursor.each(function(err, doc) {
console.log(doc);
});
})
.catch(function (err) {console.log(err)})
Where am I going wrong?
Use hasNext(). It will move to the next doc in the cursor until it reaches to the end. Also get the database name before querying the collection
var DbName = db.db("databaseNameHere");
var cursor = DbName.collection("product_catalog").find();
while (cursor.hasNext()) {
console.log(tojson(cursor.next()));
}
Change your code to:
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/mcart'
MongoClient.connect(url)
.then(function (db) {
console.log("Before")
var DbName = db.db("databaseNameHere");
var cursor=DbName.collection("product_catalog").find();
while (cursor.hasNext()) {
console.log(tojson(cursor.next()));
}
console.log("after")
})
.catch(function (err) {})
As you are using ^3.0.x this is the way to connect and execute queries.
Using MongoDB nodejs driver with version ^3.0.x gives you client object as callback function argument.
MongoClient.connect('mongodb://localhost:27017', (err, client) => {
if(err)
throw err
// Client returned
var db = client.db('mcart');
db.collection("product_catalog").find();
...
});
The way you're doing is the old way, used in 2.x version where it gives you db object as an argument to the callback function.
Read more about the change logs here
I tried the below code and this is working fine. This code is basically a combination of the other two answers. Just posting it for others in future.
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017'
var databaseName="mcart";
MongoClient.connect(url)
.then(function (mongoClientInstance) {
var database = mongoClientInstance.db(databaseName);
var x=database.collection("product_catalog").find().toArray();
return x;
})
.then(x=>console.log(x))
.catch(err=>console.log(err))

Connect synchronously to mongodb

I would like to connect to mongodb first, then run everything else in my application.
To do it I have to write something like:
MongoClient.connect("mongodb://localhost/test", function(err, connection) {
if (err) { console.error(err); }
db = connection;
var app = express();
// Include API V1
require("./apiv1.js")(app, db);
app.listen(3000, function(err) {
if (err) { console.error(err); } else { console.log("Started on *:3000"); }
});
});
This makes my app to be completely indented inside the .connect function... Which looks ugly and takes space while I work on my project.
I think the best solution would be have the MongoDB connection synchronous (even because witout the DB connection my app cannot work so why should I do something while it's connecting?) and then run the rest of my code.
How can I do?
You can't connect to MongoDB synchronously, but you may get rid of this ugly callback from your code.
The best way to do it is to adopt some wrapper around node-mongodb-native driver.
Take a look at the following modules.
mongojs
var mongojs = require('mongojs');
var db = mongojs('localhost/test');
var mycollection = db.collection('mycollection');
mongoskin
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/test", {native_parser:true});
monk
var monk = require('monk');
var db = monk('localhost/test');
var users = db.get('users')
Of course, internally all of them are establishing MongoDB connection asynchronously.
Using the async library, you can aleve some of these issues.
For example in my server startup I do the following :
async.series([
function(callback){
// Initialize the mongodb connection and callback on completion in init.
db.init(function(){
callback();
});
},
function(callback){
// Listen on requests etc.
webServer.init(function(){
callback();
});
},
function(callback){
// Set up anything else that I need
callback();
}
]);
If you are using Node 6 and up versions, you can do something like this:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/mydb';
let db = null;
getdb();
//your code
async function getdb() {
db = await MongoClient.connect(url);
}
Bring the mongodb library.
Declare the url constant .
Declare the variable db as null.
Call the getdb function.
Create the getdb function which has firt the async word
Assign to the db variable the result of the connection with the key word await.
You can do it with thunky, thunky executes an async function once and caches it, the subsequent calls are returned from the cache.
const MongoClient = require('mongodb').MongoClient;
const thunky = require('thunky');
var connect = thunky(function(cb){
let url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, client){
console.log('connecting')
cb(err, client);
})
})
connect( (err, client) => {
console.log('connection 1')
})
connect( (err, client) => {
console.log('connection 2')
})
connect( (err, client) => {
console.log('connection 3')
console.log('closing')
client.close();
})
*Note: I am using latest 3.x mongodb driver

Resources