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();
})
};
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()
})
The connection is closing, but your program is exiting before the callback is invoked.
To confirm, try:
process.on('SIGINT', () => {
disconnectDB(true);
})
const disconnectDB = function (exit=false) {
db.close(function () {
console.log('Mongoose default connection disconnected through app termination')})
if (exit) process.exit()
})
// mongoose.disconnect(function () {
// console.log('Mongoose default connection disconnected through app termination')})
}
Related
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();
}
}
}
I would like to configure my project in order to run unit test for some API endpoints (that call the database). I'm using :
ExpressJS
MongoDB (no Mongoose)
Mocha / Chai
Mongodb Memory Server (to mock the DB)
// app.ts
export const app = express();
const port = process.env.PORT;
app.use("/my-route", myRoutes);
mongoConnect().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});
// database.ts
export const mongoConnect = async () => {
try {
let MONGODB_URI = process.env.MONGODB_URI;
if (process.env.NODE_ENV === "test") {
const mongoServer = await MongoMemoryServer.create();
MONGODB_URI = mongoServer.getUri();
}
const client: MongoClient = await MongoClient.connect(MONGODB_URI);
_db = client.db("dbName");
_mongoClient = client;
if (process.env.NODE_ENV === "test") {
console.log("Connected to MongoDB Test");
} else {
console.log("Connected to MongoDB");
}
} catch (err) {
console.log("Error connecting to MongoDB:", err);
throw err;
}
};
export const getMongoClient = () => {
if (_mongoClient) {
return _mongoClient;
}
throw "Mongo client doesn't exist";
};
export const getDb = () => {
if (_db) {
return _db;
}
throw "No database found!";
};
// test.ts
let mongoClient: MongoClient;
let db: Db;
before(function (done) {
mongoConnect()
.then(() => {
db = getDb();
mongoClient = getMongoClient();
return db.createCollection("wordsCollection");
})
.then(() => {
db.collection("wordsCollection").insertMany(data);
})
.catch((err) => console.log(err))
.finally(() => done());
});
after(function (done) {
db.dropDatabase();
mongoClient.close().then(() => {
done();
});
});
it("test", async function () {
let res = await chai
.request(app)
.post("/my-route/hello")
.send({ excludeIds: [] });
expect(res.status).to.equal(200);
});
});
But it's not working...
If I call mongoConnect() in test.ts it console.log twice Connected to MongoDB Test. But if I don't call the function it throws me error because MongoClient is undefined.
I think await chai.request(app) already calls the database and server but I need to create Collection and Documents before. So I need to connect to the DB before the test.
Any help would be greatly appreciated.
I found a solution, I don't know if it's best practice but it works and is pretty easy, thanks to this post : https://stackoverflow.com/a/70285190/10547153.
I needed to add a condition in app.ts before making the connection to the database and the server in order to launch them only if it's called by Node itself.
if (require.main === module) {
mongoConnect().then(() => {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
});
}
When a file is run directly from Node.js, require.main is set to its
module. That means that it is possible to determine whether a file has
been run directly by testing require.main === module.
Now I can connect to the mocked database from test.ts and only one connection will be triggered.
I have a node typescript project where I have created a TS file for the Redis connection which is below.
import { createClient } from 'redis';
import { promisify } from 'util';
import Logger from 'utils/logger';
const { REDIS_URL = 'redis://localhost:6379' } = process.env;
const options = {
legacyMode: true,
url: REDIS_URL,
}
const client = createClient(options);
// client.connect();
client.on('connect', () => {
Logger.info("Connected to Redis");
});
client.on('error', err => {
Logger.error('redis error: ' + err);
init();
});
client.on('ready', err => {
Logger.info("redis is ready");
});
client.on('end', err => {
Logger.info("redis connection is ended");
});
//reconnecting
client.on('reconnecting', err => {
Logger.info("redis connection is reconnecting");
});
const init = async () => {
await client.connect();
}
export { init,client };
then I am importing it and connected it to index.ts
import { init } from 'dataSource/redis';
(async () => {
await init();
})();
app.listen(PORT,() => {
// console.log(`server is running on PORT ${PORT}`)
Logger.info(`Server Started in port : ${PORT}!`);
})
then I am trying to use the client in my controller file.
import { client as redisClient } from 'datasource/redis';
redisClient.setEx("Key",Number(process.env.REDIS_EXPIRE_TIME),"VALUE");
but I am getting this error
Error: The client is closed
uncomment the "client.connect();" on line 13.
This should make it work
I cannot make MongoClient.connect to await for the results before going on.
I am trying to pass db from the server.js, where I connect my mongoclient, to my routes/api.js where I do my post requests. But it does not work, I always get:
TypeError: Cannot read property 'collection' of undefined
Here is my routes/api.js:
var db = require("../server");
router.post('/video_url', async (req, res) => {
const cursor = db.collection('movie').findOne({ link: req.body.videoURL }, function (findErr, result) {
if (findErr) throw findErr;
console.log(cursor)
});
server.js:
var db = async function () {
return await MongoClient.connect(MONGODB_URI, function(err, client) {
try {
if(err) throw err;
db = client.db('sub-project');
// Start the application after the database connection is ready
app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));
return db;
}
catch(ex) {
console.log(ex)
}
});
}
module.exports = db;
EDIT:
var dbObject = (async function() {
var connection = await new Promise(function(resolve, reject) {
MongoClient.connect(MONGODB_URI, { useNewUrlParser: true }, function(err, client) {
try {
if (err) throw err;
db = client.db('sub-project');
// Start the application after the database connection is ready
app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));
resolve(db);
} catch (ex) {
console.log(ex)
reject(ex);
}
});
});
return connection;
})();
console.log("TYPEOF DB IN", typeof(dbObject))
console.log("TYPEOF DB.COLLECTION IN", typeof(dbObject.collection))
The both console.log() are undefined... is that normal?
Use this code for your server.js. Your code was not working because your function was not getting called when you are requiring it.
var dbObject;
(function() {
MongoClient.connect(MONGODB_URI, { useNewUrlParser: true }, function(err, client) {
try {
if (err) throw err;
db = client.db('sub-project');
// Start the application after the database connection is ready
app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));
dbObject = db;
} catch (ex) {
console.log(ex);
}
});
})();
setTimeout(function() {
console.log("TYPEOF DB IN", typeof(dbObject))
console.log("TYPEOF DB.COLLECTION IN", typeof(dbObject.collection))
}, 2000);
module.exports = dbObject;
When am trying to save a document in a collection or find the list of collections in mongodb running remotely doesnt work but works when am connecting to mongo db locally. save doesnt show if it throwed an error or it was successful.
Your help is appreciated.
below is my code
var mongoose = require('mongoose');
var dbName = 'OST';
var connectionString = 'mongodb://vm-1b98-f53f.nam.nsroot.net:32017/OST?ssl=true&sslverifycertificate=false';
mongoose.connect(connectionString);
mongoose.connection.on('error', function (err) {
console.log('Mongoose default connection error: ' + err);
});
mongoose.connection.on('connected', function () {
console.log('Mongoose default connection open to ' + connectionString);
var Region = require('./Region.js');
var r = new Region({ NodeID: 8687, RegionName: 'EMEA' });
r.save(function (err, regionObj) {
if (err) {
console.log('error');
throw err;
} else {
console.log('saved successfully:', regionObj);
}
});
mongoose.connection.db.collectionNames(function (error, names) {
if (error) {
console.log(error);
} else {
names.map(function (cname) {
console.log(cname.name);
});
}
});
});
process.on('SIGINT', function () {
mongoose.connection.close(function () {
process.exit(0);
});
});