Unable to close mongoose connection - mongodb

I am unable to close mongoose connection when I am storing mongoose.connection in a variable called db and creating a separate method to closing the connection via variable db I have tried both method db.close & mongoose.disconnect()
const mongoose = require('mongoose');
var db;
const connectToDB = function (callback) {
let dbUrl;
if (environmentTokens.enviroment === "test") {
dbUrl = localDBUrl;
} else {
dbUrl = environmentTokens.mongoDBUrl;
}
mongoose.connect(dbUrl);
db = mongoose.connection
db.on('error', (err) => {
tracer.error('Connection error with database', err);
})
db.on('connected', () => {
tracer.info('Connected with database', dbUrl);
console.log('Mongoose default connection connected');
callback();
})
// db.on('disconnected', function () {
// console.log('Mongoose default connection disconnected');
// });
// mongoose.connection.close(function () {
// console.log('Mongoose default connection disconnected through app termination')})
};
const getDB = function () {
return db;
};
const disconnectDB = function () {
db.close(function () {
console.log('Mongoose default connection disconnected through app termination')})
// mongoose.disconnect(function () {
// console.log('Mongoose default connection disconnected through app termination')})
}
module.exports = {
connectToDB, disconnectDB, getDB
};
And calling the disconnectDB method from index.js file
process.on('SIGINT', () => {
disconnectDB();
process.exit()
})
I tried to close the connection using following method
mongoose.disconnect(function () {
console.log('Mongoose default connection disconnected');
});
mongoose.connection.close(function () {
console.log('Mongoose default connection disconnected through app termination')})
within disconnectDB method but non of them is closing the connection but when i am using these method inside connectToDB then i am able to close the connection. DOn't understand why this is behaving like this

Related

NextJs TypeError: Cannot read properties of undefined (reading '0')

I am trying to connect to Mongodb to define connect, disconnect and use it in an API. I receive this TypeError of cannot read properties of undefined (reading '0). I console to check if the array containing all connections associated with this Mongoose instance but had only 0 instead of list of connections. Below is the Code Snippet.
import mongoose from 'mongoose';
const connection = {};
async function connect() {
if (connection.isConnected) {
console.log('already connected');
}
if (mongoose.connections.length > 0) {
connection.isConnected = mongoose.connections[0].readyState;
console.log('cone', connection.isConnected);
if (connection.isConnected === 1) {
console.log('use previous connection');
return;
}
await mongoose.disconnect();
}
const dbConnect = mongoose.connect(process.env.MONGODB_URI, {
// useNewUrlParser: true,
useUnifiedTopology: true,
// useCreateIndex: true,
});
console.log('new connection');
connection.isConnected = dbConnect.connections[0].readyState;
}
async function disconnect() {
if (connection.isConnected) {
if (process.env.NODE_ENV === 'production') {
await mongoose.disconnect();
connection.isConnected = false;
} else {
console.log('not disconnected');
}
}
}
const db = { connect, disconnect };
export default db;
The Error I get is this
error - (api)\utils\db.js (25:49) # Object.connect
TypeError: Cannot read properties of undefined (reading '0')
23 | });
24 | console.log('new connection');
> 25 | connection.isConnected = dbConnect.connections[0].readyState;
| ^
26 | console.log("cone1", connection.isConnected);
27 | }
There were no types on the mongoose.connect() as connections. So just needed to remove the connections[0].readyState I was looking for.
import mongoose from 'mongoose';
const connection = {};
async function connect() {
if (connection.isConnected) {
console.log('already connected');
return;
}
if (mongoose.connections.length > 0) {
connection.isConnected = mongoose.connections[0].readyState;
if (connection.isConnected === 1) {
console.log('use previous connection');
return;
}
await mongoose.disconnect();
}
const options = {
useUnifiedTopology: true,
useNewUrlParser: true,
};
const uri = process.env.MONGODB_URI;
const db = mongoose.connect(uri, options);
console.log('new connection');
connection.isConnected = db
if (!uri) {
throw new Error('Add your Mongo URI to .env');
}
}
async function disconnect() {
if (connection.isConnected) {
if (process.env.NODE_ENV === 'production') {
await mongoose.disconnect();
connection.isConnected = false;
} else {
console.log('not disconnected');
}
}
}
const db_export = { connect, disconnect };
export default db_export;

Socket.io, Mongodb returning undefined to frontend

I want to use socekt.io for a new project I am building. I am using socket.io for a login component and will be using socket.io in the future to update pages like a chat app. I am also using mongoose to handle my mongodb connection. I am taking in a username, and returning a password to my front end to be bcryptjs compareSync hashed. The problem I am having is that whatever is returned to the front end is undefined. When I print out what is returned to the front end, it prints out the value I am looking for though. Something is going on between the backend emitting something, and the frontend receiving something but I don't know what is it exactly. Here is my code for the back end:
const express = require('express')
const socket = require('socket.io');
const http = require('http');
const router = require('./router');
const mongoose = require('mongoose');
let Player = require('../models/player.model');
require('dotenv').config();
const PORT = process.env.PORT || 5000;
const app = express();
const server = http.createServer(app);
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, {useNewUrlParser: true, useCreateIndex: true,
useUnifiedTopology: true });
const connection = mongoose.connection;
connection.once('open',() => {
console.log('MongoDB database connection established successfully')
});
const io = socket(server);
io.on('connection', (socket) => {
console.log('We have a new connection');
socket.on('login', ({ username }, callback) => {
console.log(username);
Player.find({"username": username}, function (err, player) {
if(err) {
console.log("there has been an error"), {player: null}
}
socket.emit('id', { password: player[0]['password'].toString(), id : player[0]['_id']})
}) })})
app.use(router);
server.listen(PORT, () => console.log('Server is working'))
Here is my code for the front end:
const ENDPOINT = 'localhost:5000';
async function submitAccount (e) {
e.preventDefault();
socket.emit('login', { username });
socket.on("id", (response) => {
setPassword2(String(response['password']));
id = response['id']; console.log(id);
console.log(password2)
});
try {
if (bcrypt.compareSync(password, password2) == true) {
props.setCookie("id", id);
setAccess(true);
access2 = true;
console.log(access2)
console.log('works')
}
else {
setErrorType('Invalid Password')
setErrorMsg('There is an issue with your password. Please try again')
setOpenModal(true)
console.log(password);
console.log(password2);
}
}
catch {
setErrorType('Invalid Username')
setErrorMsg('This username does not exist. Please try another')
setOpenModal(true)
}
Thanks for the help!
When you do the socket.on, it should include the whole statement you are looking to change with the socket.io output. See below:
async function submitAccount (e) {
e.preventDefault();
socket.emit('login', { username });
socket.on("id", (response) => {
setPassword2(String(response['password']));
id = response['id']; console.log(id);
console.log(password2)
if (password2 != undefined) {
try {
if (bcrypt.compareSync(password, password2) == true) {
props.setCookie("id", id);
setAccess(true);
access2 = true;
console.log(access2)
console.log('works')
}
}

How to get MongoClient object from Mongoose?

I have to get the MongoClient object from mongoose connection object, so that I can reuse for Agenda or somewhere else where I need.
db.js
// Export the mongoose instance
module.exports = () => {
mongoose.Promise = global.Promise;
try {
console.log('DBURL:', dbConfig.url);
const { url, options } = dbConfig;
mongoose
.connect(url, options)
.then(() => console.log('DB Connected'), err => console.log(err, options));
mongoose.connection.on('connected', () => {
logger.log('info', 'Mongoose default connection opened');
});
mongoose.connection.on('error', (err) => {
// logger.log('error', 'Couldn't able to connect to MongoDB', err);
// Blow system on db error
logger.log('info', 'Mongoose default connection opened');
throw err;
});
mongoose.connection.on('reconnected', () => {
logger.log('info', 'Mongo connection reconnected', arguments);
});
mongoose.connection.on('disconnecting', () => {
logger.log('error', 'Mongoose connection disconnecting', arguments);
});
mongoose.connection.on('disconnected', () => {
logger.log('error', 'Mongoose connection disconnected', arguments);
});
} catch (e) {
console.log("Couldn't connect to mongo:", e);
}
return mongoose;
};
You can get the mongoClient with getClient() method as shown in the docs: getClient()
Basically you need to do something like this
const client = mongoose.connection.getClient()
So to use it with connect-mongo for example you could just export that from your db.js then import and use where needed.
//db.js
module.exports.client = mongoose.connection.getClient()
//app.js
const { client } = require('path to file')
const store = MongoStore.create({ client })
const mongoose = require("mongoose");
let options = { //Your options };
const mongoClient = new mongoose.mongo.MongoClient(URI, options)
config = require('./configs');
mongoose = require('mongoose');
module.exports = function() {
var db = mongoose.connect(config.db, config.mongoDBOptions).then(
() => {
console.log('MongoDB connected')
},
(err) => {
console.log('MongoDB connection error',err)
}
);
require('../app/models/xxx.server.model');
require('../app/models/yyy.server.model');
return db;};
You may get MongoClient Object by following this method:
const { MongoClient, ObjectID } = require('mongodb');
function(req, res) {
(async function mongo() {
let client;
try {
client = await MongoClient.connect(url, {useNewUrlParser: true});
debug('Connected correctly to server');
const db = client.db(dbName);
}

How avoid "Can't set headers after they are sent."

I use mongodb and in mongodb I put my username and password.
The code is:
var mongodb = require('mongodb');
var http = require('http');
var fs=require('fs');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});
app.post('/prova', function(req, res) {
// res.send('You sent the name "' + req.body.username + '".');
var MongoClient = mongodb.MongoClient;
// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost:27017/utente';
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established to', url);
var collection = db.collection('login');
// var prova1=({name:"documento1",url:"sadsad",tag:"dc1"});
// do some work here with the database.
var cursor = collection.find();
cursor.each(function (err, doc) {
if (err) {
console.log(err);
} else {
// console.log('Fetched:', doc);
var username=0;
var password=0;
for(valore in doc){
if(valore!="_id"){
if(valore=="username"){
if(doc[valore]==req.body.username){
username=1;
}
}
if(valore=="password"){
if(doc[valore]==req.body.password){
password=1;
}
}
}
}
if(username==1 && password==1){
console.log("entra");
// res.end();
}else{
fs.readFile('C:\\Users\\Eventi\\Desktop\\Node.js\\Progetti\\ProveNodeJS\\NodeJSProve\\paginaRifiuto.html', function (err, html) {
if (err) {
}
res.writeHeader(200, {"Content-Type": "text/html"});
res.write(html);
res.end(html);
});
}
}
});
//Close connection
}
});
});
http.createServer(function(request, response) {
fs.readFile('C:\\Users\\Eventi\\Desktop\\Node.js\\Progetti\\ProveNodeJS\\NodeJSProve\\home.html', function (err, html) {
if (err) {
}
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
});
}).listen(8000);
I call first http://localhost:8000 and I put in a text field the wrong value of username and password and after I click login I see my "login fail page" but I obtain this error:
Connection established to mongodb://localhost:27017/utente
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.writeHead (_http_server.js:195:21)
at ServerResponse.writeHeader (_http_server.js:233:18)
at C:\Users\Eventi\Desktop\Node.js\Progetti\ProveNodeJS\NodeJSProve\HelloWord.js:67:23
at fs.js:334:14
at FSReqWrap.oncomplete (fs.js:95:15)

How to connect to MongoDb with Hapi.js?

Does anyone know how to connect to MongoDb while using the Hapi.js framework?
I have only managed to find one example (https://github.com/Marsup/hapi-mongodb), but this requires using a plugin and has no comments in the code!
Does anyone know of a simpler way?
The following (using mongoose) works pretty well for me:
var Hapi = require('hapi');
var mongoose = require("mongoose");
var server = new Hapi.Server();
server.connection({ port: 3000 });
var dbUrl = 'mongodb://localhost:27017/mydb';
var dbOtions = {
db: { native_parser: true },
server: { poolSize: 5 }
};
server.register([ /* plugins */], function (err) {
if (err) {
throw err; // something bad happened loading the plugins
}
// ... Register the routes
server.start(function () {
mongoose.connect(dbUrl, dbOtions, function(err) {
if (err) server.log('error', err);
});
});
});
I use a hapi plugin that I wrote that connects to mongo, handles errors to log and adds bluebird promises.
'use strict';
var bluebird = require('bluebird');
var mongoose = bluebird.promisifyAll(require('mongoose'));
exports.register = function(plugin, options, next) {
mongoose.connect(options.mongo.uri, options.mongo.options, function (e) {
if (e) {
plugin.log(['error', 'database', 'mongodb'], 'Unable to connect to MongoDB: ' + e.message);
process.exit();
}
mongoose.connection.once('open', function () {
plugin.log(['info', 'database', 'mongodb'], 'Connected to MongoDB # ' + options.mongo.uri);
});
mongoose.connection.on('connected', function () {
plugin.log(['info', 'database', 'mongodb'], 'Connected to MongoDB # ' + options.mongo.uri);
});
mongoose.connection.on('error', function (e) {
plugin.log(['error', 'database', 'mongodb'], 'MongoDB ' + e.message);
});
mongoose.connection.on('disconnected', function () {
plugin.log(['warn', 'database', 'mongodb'], 'MongoDB was disconnected');
});
});
return next();
};
exports.register.attributes = {
name: 'mongoose',
version: '1.0.0'
};
Blog post on user authentication with passport and Mongoose
Also be aware that Hapi's model is based off of plugins so read and re-read the docs on building your own.
Visit http://cronj.com/blog/hapi-mongoose
Complete sample project which can help you Repo Link https://github.com/gauravgupta90/Hapi-Mongoose-Angular
Config.js
module.exports = {
server: {
host: '0.0.0.0',
port: 8000
},
database: {
host: '127.0.0.1',
port: 27017,
db: 'DatabaseName',
username: '',
password: ''
}
};
Server.js
var Hapi = require('hapi'),
Routes = require('./routes'),
config = require('./config'),
Db = require('./database');
var server = Hapi.createServer(config.server.host, config.server.port, {
cors: true
});
server.route(Routes.endpoints);
server.start(function() {
console.log('Server started ', server.info.uri);
});
Database.js
var Mongoose = require('mongoose'),
config = require('./config');
Mongoose.connect('mongodb://' + config.database.host + '/' + config.database.db);
var db = Mongoose.connection;
db.on('error', console.error.bind(console, 'connection error'));
db.once('open', function callback() {
console.log("Connection with database succeeded.");
});
exports.Mongoose = Mongoose;
exports.db = db;
The following works for me:
const Hapi = require("hapi");
const Mongoose = require("mongoose");
const server = new Hapi.Server({ "host": "localhost", "port": 3000 });
Mongoose.connect('mongodb://localhost:27017/testdb', { useNewUrlParser: true }, (err) => {
if (!err) { console.log('MongoDB Connection Succeeded.') }
else { console.log(`Error in DB connection : ${err}`)}
});