Await the database connection - node.js

I need to wait the MongoDB database connection.
I have a function that makes a connection and puts a database object into a global variable.
I also have a server startup function in which I want to call the database connection function
async function connectDB() {
const client = new MongoClient(config.DBURL, {useNewUrlParser: true, useUnifiedTopology: true});
await client.connect(err => {
if (err) {
throw err
}
global.dbClient = client
global.db = client.db("db")
console.log("Database Connected!")
});
}
module.exports = {
connectDB: connectDB
}
const connectDB = require('./db').connectDB
app.listen(port, async () => {
await connectDB()
console.log('Server started on: ' + port);
});

I assume your problem is that await client.connect doesn't actually wait. That would indicate that client.connect doesn't actually return a Promise. But you can wrap it in your own:
async function connectDB() {
const client = new MongoClient(config.DBURL, { useNewUrlParser: true, useUnifiedTopology: true });
return new Promise((resolve, reject) => {
client.connect(err => {
if (err) return reject(err);
global.dbClient = client;
global.db = client.db("db");
console.log("Database Connected!");
resolve(client);
});
});
}

Related

MongoDB won't insert document

I don't know what I am doing wrong, however the following is not working.
I have the database connecting however when I try and use the connection it won't let me.
index.js
config = require('./config');
const express = require('express');
const app = express();
const mDB = require('./components/mongodb').connect(config.dbUri);
app.get('/testDB', (req,res) =>{
const user = { name: 'John', age: 30 };
mDB.insertOne(user, (error, result) => {
if (error) {
console.log(error);
return;
}
console.log(`Successfully inserted user: ${result.insertedId}`);
res.send("inserted");
});
});
app.listen(3000, () => {
console.log('App listening on port 3000');
});
./components/mongodb.js
const MongoClient = require('mongodb').MongoClient;
module.exports.connect = (uri) => {
MongoClient.connect(uri, { useNewUrlParser: true }, (err, client) => {
if (err) {
console.error(`MongoDB connection error: ${err}`);
process.exit(1);
}
console.log('Successfully connected to MongoDB');
module.exports.client = client;
});
};
module.exports.insertOne = (collection, document) => {
module.exports.client.db('PodToo').collection(collection).insertOne(document, (error, result) => {
if (error) {
console.log(error);
return;
}
console.log(`Successfully inserted document: ${result.insertedId}`);
});
};
I get the Successfully connected to MongoDB
But then when I try and use it I am receiving
TypeError: Cannot read properties of undefined (reading 'insertOne')
In the danger of stating the obvious: You are missing the first argument to your insertOne function, the collection name.
Did you mean
mDB.insertOne('users', user, ...
?

Error: MongooseError: Operation `tours.insertOne()` buffering timed out after 10000ms at Timeout.<anonymous>

I'm running MongoDB Atlas on node express and I got this error.
Also I have set my network access from anywhere.
Every time I use testTours.save() method it somehow invokes the tours.insertOne() method and creates a collection by itself.
What to do?
Here is my code:
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const app = require('./app');
dotenv.config({ path: './config.env' });
const DB = process.env.DATABASE.replace(
'<PASSWORD>',
process.env.DATABASE_PASSWORD
);
async function start() {
try {
await mongoose.connect(DB, () => console.log('DB connection successful'));
} catch (err) {
console.log(err);
}
}
start();
testTour
.save()
.then(doc => {
console.log(doc);
})
.catch(err => {
console.log('Error: ', err);
});
const port = 3000 || process.env.PORT;
app.listen(port, () => {
console.log(`Listening on port ${port}...`);
});
You have to wait for connection to be established
start().then(() => {
testTour
.save()
.then(doc => {
console.log(doc);
})
.catch(err => {
console.log('Error: ', err);
});
})

Can .save() Mongoose Schema only one time, next i need to restart node.js server to save it again

i have this problem. First i start Mongoose connecting it to Atlas Db.
dbConfig.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://myMongoDbOnAtlas?retryWrites=true&w=majority";',
{
useUnifiedTopology: true,
useNewUrlParser: true,
}
);
mongoose.connection.once('open', () => {
console.log('Connected to db');
}).on('error', (error) => {
console.warn('Error: ' + error);
})
module.exports = mongoose;
/db/schema/offices.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const OfficeSchema = new Schema({
// Some Properties
});
const Office = mongoose.model('offices', OfficeSchema);
module.exports = Office;
addOfficeController.js
const Office = require('../db/schema/office');
const mongoose = require('../db/dbConfig');
const addOffice = async (req, res, next) => {
const office = req.body;
let newOffice = new Office(office);
newOffice.save((err, data) => {
if(err){
res.status(400).send(err);
console.log(err);
}else{
res.status(201).send(data);
}
mongoose.connection.close();
})
};
module.exports = {
addOffice
};
Now when i start the Node server my controller works fine and save on db the data, but if i try to do it again the callback is an error: MongooseError: Operation offices.insertOne() buffering timed out after 10000ms
Ok i solved in this way
const mongoose = require('mongoose');
const startDb = () => {
mongoose.connect('myMongoDb#cluster0.hazp8.mongodb.net/db?retryWrites=true";',
{
useUnifiedTopology: true,
useNewUrlParser: true,
}
);
mongoose.connection.once('open', () => {
console.log('Connected to db');
}).on('error', (error) => {
console.warn('Error: ' + error);
})
}
module.exports = startDb;
I exported a function that starts the connection to db, and after save() I close the connection.

Mongodb-mongoose collections undefined

I am new and practicing Mongoose and Mongodb connection. I successfully connect my database to my local machine and get log confirmations. I am trying get my collection without passing mongoose Schema but I am getting error: TypeError: Cannot read property 'collection' of undefined. I don't know what I am doing wrong.
Here is code:
require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
const { Schema } = mongoose;
const app = express();
mongoose
.connect(process.env.MONGODB_URI, {
useUnifiedTopology: true,
useNewUrlParser: true
})
.then(() => console.log("DB Connected!"))
.catch(err => {
console.log(err);
});
var connection = mongoose.connection;
connection.db.collection("bags", function (err, collection) {
collection.find({}).toArray(function (err, data) {
console.log(data); // it will print your collection data
})
});
You're trying to access the DB before the connection is established to MongoDB. ( Connecting to DB is asynchronous code )
Also, Read - https://javascript.info/async-await
mongoose
.connect(process.env.MONGODB_URI, {
useUnifiedTopology: true,
useNewUrlParser: true
})
.then(() => {
console.log("DB Connected!");
var connection = mongoose.connection;
// run logic once db is connected.
connection.db.collection("bags", function (err, collection) {
collection.find({}).toArray(function (err, data) {
console.log(data); // it will print your collection data
})
});
})
.catch(err => {
console.log(err);
});
Or
mongoose.connection.on('connected', err => { // will trigger connected event when connected to MongoDB
var connection = mongoose.connection;
connection.db.collection("bags", function (err, collection) {
collection.find({}).toArray(function (err, data) {
console.log(data); // it will print your collection data
})
});
});

How can I test mongoose session transactions. Error: MongooseError: Connection 1 was disconnected when calling `startSession

I am testing out mongoose atomic transactions. While creating a user, I perform all operations under a transaction. This works just fine in the development environment but fails when running tests
// db connection
const { MongoMemoryReplSet } = require('mongodb-memory-server');
if (process.env.NODE_ENV === 'testing') {
const replSet = new MongoMemoryReplSet({
replSet: { storageEngine: 'wiredTiger' },
});
await replSet.waitUntilRunning();
const uri = await replSet.getUri();
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
} else {
mongoose.connect(settings.uri, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
replicaSet: 'rs',
});
}
// user controller
const mongoose = require('mongoose');
controller.createUser = async (req, res) => {
const session = await mongoose.startSession();
session.startTransaction();
const user = new User({username: req.body.username})
try {
await user.save({ session });
await session.commitTransaction();
...
} catch (err) {
await session.abortTransaction();
throw new Error(err)
} finally {
session.endSession();
}
...
}
// test
describe('user api routes', () => {
it('should create a user', async () => {
const res = await request(app).post('/api/v1/users').send({});
})
npm test
Error MongooseError: Connection 0 was disconnected when calling `startSession
When I remove the transaction code and session, it works just fine.
How can I ensure that while running tests, I can start a session and not close the connection?

Resources