Mongoose & MongoDB connection on production - node.js

What are best practicies to handle mongodb connection using mongoose on production?
This is my code
connectToDatabase.js
'use strict';
const mongoose = require('mongoose');
const mongodb = require('mongodb');
mongoose.Promise = require('bluebird');
const { Db, Server } = mongodb;
const database = 'test';
const connectToDatabase = (callback) => {
if (process.env.NODE_ENV == 'test') return false;
const db = new Db(database new Server('localhost', 27017));
db.open()
.then(() => {
mongoose.connect(`mongodb://localhost/${database}`, { config: { autoIndex: false } });
mongoose.connection
.once('open', () => {
console.log(`Connected to database ${database}`);
callback(db);
})
.on('error', (error) => {
console.warn('Warning', error);
});
});
};
module.exports = connectToDatabase;
app.js
const connectToDatabase = require('./connectToDatabase');
connectToDatabase(() => {
// run server
});
I don't know exactly what happening when connection to database is interrupted, Is mongoose trying connect to database again?

Related

showing undefined when trying to access the collection using nodejs

i am trying to display all the documents in a collection called tutorial so i am using a simple code here's my code
const mongodb = require("mongodb");
const express = require("express");
var app = express();
var mongoClient = mongodb.MongoClient;
var conn = "mongodb://localhost:27017";
mongoClient.connect(conn, (err, client) => {
if (err) {
console.log(err);
} else {
console.log("connection estableshed");
var db = client.db("mydb");
var collection = db.collection("tutorial");
collection.find().toArray((err, data) => {
console.log(data);
});
client.close();
}
});
but the result i got undefined so what seems to be the problem here?
Problem with the callback, you can use then() method instead.
const mongodb = require("mongodb");
const express = require("express");
var app = express();
var mongoClient = mongodb.MongoClient;
var conn = "mongodb://localhost:27017";
mongoClient.connect(conn).then((err, client) => {
if (err) {
console.log(err);
} else {
console.log("connection established");
var db = client.db("mydb");
var collection = db.collection("tutorial");
collection
.find()
.toArray()
.then((data) => {
console.log(data);
});
client.close();
}
});
app.listen(3000, () => {
console.log("Server started");
});

why am i getting Cannot read properties of undefined (reading 'collection') in the code below?

i'm new to mongodb and dev web and i'm using mongodb with nodejs in this project and i got this problem "Cannot read properties of undefined (reading 'collection')" on postman when i send a request but in VS it connect to database without any problem could anyone help me please
here is my code
that's my connection.js and here when i hover on collection and db it says in visual code it's undefined
const {MongoClient} = require('mongodb');
const {dbURL, dbName} = require('../config');
const client = new MongoClient(dbURL, {
useUnifiedTopology: true,
useNewUrlParser:true
});
function Connect(){
return new Promise(async(resolve, reject) =>{
try {
await client.connect();
const db = client.**db**(dbName);
const users = db.**collection**('users');
users.createIndex({email: 1},{unique: 1});
resolve(db, client);
}catch(error){
reject(error);
}
});
};
module.exports = Connect;
i hope someone can find the solution here
and this is my index.js
const Connect = require('./connection');
const {port} = require('../config');
const app = require('./app');
Connect().then(({db}) => {
app.setupRoutes(db);
console.log('The database is connected');
}).catch((e) => {
console.error("couldn't connect to database", e);
});
app.listen(port, () => console.log(`App listening on port ${port}!`));
module.exports = app;
and that's my app.js
as you see i'm using db.collection here
const express = require("express");
const cors = require("cors");
const ValidationError = require('./errors/ValidationError');
const app = express();
app.use(cors());
app.use(express.json());
const handleNewUser = (user, db) => {
return new Promise(async(resolve, reject)=>{
try {
const users = db.collection('users');
const results = await users.insertOne(user);
resolve(results.insertedId);
}catch (error){
reject(error);
}
})
};
app.setupRoutes = (db) => {
app.post('/users',async (req, res) =>{
const user = req.body;
try {
const errors = validateUser(user);
if(errors.length > 0) throw new ValidationError(errors, 'Validation Error');
const results = await handleNewUser(user, db);
res.status(201).send(results);
}catch (error){
if(error instanceof ValidationError)
res.status(500).send({message:error.message,errors:error.errors});
else if(error.message.startsWith('E11000 duplicate'))
res.status(500).send('duplicate email.');
else res.status(500).send(error.message);
}
});
}
module.exports = app;
i donét know what's wrong and i'm following a tutoriel
resolve(db, client) - you resolve not object but separate values "db" and "client".
Connect().then(({db}) => { -
tries to destructure the 'db' property of the first resolved value, and if your "db" value is not an object or doesn't have .db property, it would always be undefined.
So remove destructuring and use just the value:
Connect().then((db) => {

node app on shared hosting cpanel cannot connect to mongodb

I have been trying to connect to mongodb via my node app on a shared hosting cpanel but it only responds with error code 503 and logs "db.collection undefined" to the console, which means the connection was not successful.
This is the database connection in db.js:
const { MongoClient } = require('mongodb');
require('dotenv').config();
let dbConnection;
module.exports = {
connectToDb: (cb) => {
MongoClient.connect(`mongodb+srv://Achifa:${process.env.PASSWORD}#cluster0.exp9r.mongodb.net/?retryWrites=true&w=majority`)
.then((client) => {
dbConnection = client.db('newsDb')
return cb()
})
.catch(err => {
console.log(err)
return cb(err)
})
},
getDb: () => dbConnection
}
This is the app connection in app.js:
const {connectToDb, getDb} = require('./db');
let db;
var port = process.env.PORT || 50500;
connectToDb((err) => {
if(!err){
var server = app.listen(port, () => console.log("connected"));
db = getDb();
}
})

client doesn't close that causes connection error `Topology is closed`

I use following code to connect to mongodb
conn.js
'use strict'
const { MongoClient } = require('mongodb');
const dbconfig = require('../config/index');
const client = new MongoClient(dbconfig.product.dbUrl, { useNewUrlParser: true });
client.connect(function (err) {
if (err) {
console.log(err);
} else {
console.log('mongodb connected');
}
});
const db = client.db(dbconfig.product.dbName);
module.exports = db;
user.js
const db = require("./conn");
let user = await db.collection("user").find({}).toArray();
I meet an issue that sometimes I will get an error Topology is closed, how can I close the db connection in this case? Thank you.

how to use async and await to connect to mongoDB database?

I am new to JavaScript and currently learning mongoDB with node.
The code Bellow is in callback functions but i want to connect to mongoDB database using async and await with try and catch .
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/selfdb");
mongoose.connection
.once("open", () => {
console.log("connection has been made!");
})
.on("error", (error) => {
console.log("connection error:", error);
});
I tried doing this way:
const mongoose = require("mongoose");
async function main() {
const uri = "mongodb://localhost/selfdb";
const client = new mongoose(uri);
try {
await client.connect();
console.log("connection has been made!");
} catch (e) {
client.error(e);
} finally {
await client.close();
}
}
main().catch(console.error);
but i got following error:
TypeError: mongoose is not a constructor
how could i do it the right way?
am i doing any silly mistake?
I believe the better way to connect is like this
const mongoose = require('mongoose')
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI)
console.log(`MongoDB Connected: ${conn.connection.host}`)
}
catch (error) {
console.log(error)
process.exit(1)
}
}
module.exports = connectDB
Mongo URI is in .env file, but you can replace it with your connection string (but more secure in .env file)
Then in server.js or index.js (entry file)
const connectDB = require('path_to_file')
connectDB()
I Tried this approach !! May be it could be helpful.
DBconn.js (MONGO_URL is from .env file & dev_db_url is optional here)
require('dotenv').config({ path: 'env/.env' });
const dev_db_url = 'local dev. db url is not defined.';
const mongoDB_URL = process.env.MONGO_URL || dev_db_url;
const dbOptions = {useNewUrlParser: true, useUnifiedTopology: true};
const connectDB = async (cb) => {
try {
await mongoose.connect(mongoDB_URL, dbOptions)
.then(() => {
cb();
console.log("Connected to Database");
})
} catch (error) {
console.error("Could not Connect to Database", error)
}
};
module.exports = connectDB;
Server.js (Server will start to listen only after successful DB Connect)
require('dotenv').config({ path: 'env/.env' });
const connectDB = require('./database/DBConn')
const port = process.env.PORT || 5000;
const express = require('express')
const app = express()
// Connecting to DB
connectDB(()=>{
app.listen(port, () => {
console.log(`Backend : NodeJS/express server started on http://localhost:${port}`)
})
});
Another Way :
DBconn.js
const mongoose = require("mongoose");
require('dotenv').config({ path: 'env/.env' });
const dev_db_url = 'local dev. db url is not defined.';
const mongoDB_URL = process.env.MONGO_URL || dev_db_url;
const dbOptions = {useNewUrlParser: true, useUnifiedTopology: true};
const connectDB = async () => {
try {
await mongoose.connect(mongoDB_URL, dbOptions);
} catch (error) {
console.error("Could not Connect to Database", error)
}
};
module.exports = connectDB;
Server.js (here we use .once method)
require('dotenv').config({ path: 'env/.env' });
const mongoose = require("mongoose");
const connectDB = require('./database/DBConn')
const port = process.env.PORT || 5000;
const express = require('express');
const app = express();
connectDB();
mongoose.connection.once('open', () => {
console.log('Connected to MongoDB');
app.listen(port, () => {
console.log(`Backend : NodeJS/express server started on http://localhost:${port}`)
})
});

Resources