mongodb method without function not working in nodejs - node.js

I don't know much Javascript and was making a nodejs app. My mongodb query in nodejs is working only when the query has a function method like .toArray
Here's the database.js file
const {MongoClient} = require('mongodb');
const uri = "mongodb+srv://name:pass#clusterurl/metro4?retryWrites=true&w=majority";
// all fields are correctly filled
const client = new MongoClient(uri);
try {
// Connect to the MongoDB cluster
client.connect(err =>{
if(err) throw err;
let db = client.db('metro4');
db.collection('Station').find().toArray(function(err, result){
if(err) throw err;
console.log(result);
});
let a = db.collection('Station').findOne({'_id':4});
if(a) {
console.log(a);
}
else{
console.log("No a\n");
}
module.exports = db;
});
} catch (e) {
console.error(e);
} finally {
client.close();
}
when I run the app, the db.collection('Station').find().toArray runs fine and output the result but the second query of findOne doesn't work.
Any help is appreciated.

The findOne method returns a Promise. You should handle its result in a callback function:
db.collection('Station').findOne({ _id: 4 }, function (err, a) {
if (err) {
console.log(err);
} else if (a) {
console.log(a);
} else {
console.log('No a\n');
}
});
Or using async - await:
client.connect(async (err) => {
...
let a = await db.collection('Station').findOne({ _id: 4 })
...
});
EDIT
To handle the import - export problem you should handle the datase connection operations separate async functions.
You may use the connection function to return the database instance:
const {MongoClient} = require('mongodb');
const uri = "mongodb+srv://name:pass#clusterurl/metro4?retryWrites=true&w=majority";
// all fields are correctly filled
const client = new MongoClient(uri);
const connectDB = async () => {
try {
// Connect to the MongoDB cluster
await client.connect();
return client.db('metro4');
} catch (e) {
throw e;
}
}
const disconnectDB = () => {
client.close();
}
module.exports = { connectDB, disconnectDB };
Then use these functions to handle your database related operations:
const { connectDB, disconnectDB } = require('../database');
const getStations = async () => {
const db = connectDB();
if (!db) return;
try {
const data = await db.collection('Station').find().toArray();
return data;
} catch (err) {
throw err;
} finally {
disconnectDB();
}
}
const getStation = async (id) => {
const db = connectDB();
if (!db) return;
try {
const data = await db.collection('Station').findOne({ _id: id});
return data;
} catch (err) {
throw err;
} finally {
disconnectDB();
}
}

Related

Async await in typescript not working as expected

I wrote a method in typescript which is supposed to return collection list name of mongo db.
public async getTables(): Promise<String[]> {
let collectionNames = [];
const connection = await mongoose.connect("mongodb://localhost/test");
await mongoose.connection.on('open', async function () {
mongoose.connection.db.listCollections().toArray(function (err, tables) {
console.log(tables);
tables.forEach(element => {
collectionNames.push(element["name"]);
});
console.log(collectionNames);
mongoose.connection.close();
});
});
return collectionNames;
}
Problem is instead of awaiting it returns directly empty collection list name.What is the issue here.
Because you use "await" in here,
const connection = await mongoose.connect("mongodb://localhost/test");
So, you miss "open" event that mongoose connection emit.
You can remove "await" for your program run as you expected
public async getTables(): Promise<String[]> {
let collectionNames = [];
const connection = mongoose.connect("mongodb://localhost/test");
await mongoose.connection.on('open', async function () {
mongoose.connection.db.listCollections().toArray(function (err, tables) {
console.log(tables);
tables.forEach(element => {
collectionNames.push(element["name"]);
});
console.log(collectionNames);
mongoose.connection.close();
});
});
return collectionNames;
}
Or you can write as below
public getTables(): Promise<String[]> {
return new Promise(async (resolve, reject) => {
try {
let collectionNames = [];
const connection = await mongoose.connect("mongodb://localhost/test");
mongoose.connection.db.listCollections().toArray(function (err, tables) {
console.log(tables);
tables.forEach(element => {
collectionNames.push(element["name"]);
});
console.log(collectionNames);
mongoose.connection.close();
resolve(collectionNames);
});
} catch (e) {
reject(e);
}
})
}

MongoExpiredSessionError: Cannot use a session that has ended

I got the error when I trying to connect node to the database. I used the async function and try to apply the methods in other similar questions but still got it wrong. Here is my code:
const { MongoClient } = require('mongodb')
const url = "mongodb://localhost:27017"
const client = new MongoClient(url);
async function main(){
const dbName = 'my-react-admin'
try {
await client.connect();
console.log('Connect to database!')
const db = client.db(dbName);
db.collection('users').find({}).toArray((err, data) => {
if (err) throw err
console.log(data)
})
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
main().catch(console.error);
Thank you!
I found the answer, you just have to put client.close(); to
((err, data) => { if (err) throw err console.log(data) })
just like ((err, data) => {client.close();}).
it'll work.

Can't insert JSON file into MongoDB's collection throught Node driver

I'm trying to read files from my disk and push it into MongoDB's collections, but connection closing before it done and I get error: MongoError: Topology is closed, please connect.
async function launch() {
try {
await mongo.connect();
console.log("Connection established");
const database = mongo.db('task');
const firstCol = database.collection('first');
const secondCol = database.collection('second');
const insertIntoCollection = async (file, col) => {
fs.readFile(file, async function(err, data) {
if (err) throw err;
const json = JSON.parse(data);
const result = await col.insertMany(json);
console.log(result.insertCount);
});
}
await insertIntoCollection('data/first.json', firstCol);
await insertIntoCollection('data/second.json', secondCol);
} finally {
await mongo.close();
}
}
launch().catch(console.dir);
What am I doing wrong?
In the above case mongo client will close before the insertIntoCollection function trigger since it is a promise function and promise will not over before the finally trigger.I hope below code will fulfil your expectations.
async function launch() {
try {
await mongo.connect();
console.log("Connection established");
const database = mongo.db('task');
const firstCol = database.collection('first');
const secondCol = database.collection('second');
const insertIntoCollection = async (file, col) => {
return new Promise((resolve, reject) => {
fs.readFile(file, async (err, data) => {
try {
if (err) reject(err);
const json = JSON.parse(data);
const result = await col.insertMany(json);
console.log(result.insertCount);
resolve(result.insertCount)
} catch (err) {
reject(err)
}
});
})
}
await insertIntoCollection('data/first.json', firstCol);
await insertIntoCollection('data/second.json', secondCol);
} finally {
await mongo.close();
}
}
launch().catch(console.dir);

I am getting UnhandledPromiseRejectionWarning error when trying to connect node js with mongoDB Atlas cloud

I created a app.js file and there I am trying to connect with mongoDB atlas. The error 'UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()' is throwing when I run in terminal.
const connect = async function () {
const MongoClient = require('mongodb').MongoClient;
const uri = "mymongoDB atals url for nodejs";
MongoClient.connect(uri, { useNewUrlParser: true });
const collection = client.db("feedback").collection("itinerary");
// perform actions on the collection object
client.close();
};
connect().then(() => {
console.log('handle success here');
}).catch((exception) => {
console.log('handle error here: ', exception)
})
Try putting the async function operations in try catch block as below. I hope this should do the work.
const connect = async function () {
try {
const MongoClient = require('mongodb').MongoClient;
const uri = "mymongoDB atals url for nodejs";
MongoClient.connect(uri, { useNewUrlParser: true });
const collection = client.db("feedback").collection("itinerary");
// perform actions on the collection object
client.close();
} catch (e) {
console.log("Error", e)
}
};
connect().then(() => {
console.log('handle success here');
}).catch((exception) => {
console.log('handle error here: ', exception)
})
Try this:
const MongoClient = require('mongodb').MongoClient;
const connect = function () {
return new Promise((resolve, reject) => {
try {
const uri = "mymongoDB atals url for nodejs";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
if (err) {
reject(err)
}
const collection = client.db("feedback").collection("itinerary");
client.close();
resolve();
});
} catch (e) {
reject(e);
}
})
};
connect().then(() => {
console.log('handle success here');
}).catch((exception) => {
console.log('handle error here: ', exception)
})
Try this approach:
const MongoClient = require('mongodb').MongoClient;
// replace the uri string with your connection string.
const uri = "mymongoDB atals url for nodejs"
MongoClient.connect(uri, function(err, client) {
if(err) {
console.log('handle error here: ');
}
console.log('handle success here');
const collection = client.db("feedback").collection("itinerary");
// perform actions on the collection object
client.close();
});
Try by wrapping all the content of your function in a try/catch block:
const connect = async function () {
try {
const MongoClient = require('mongodb').MongoClient;
const uri = "mymongoDB atals url for nodejs";
MongoClient.connect(uri, { useNewUrlParser: true });
// most probably this is throwing the error. Notice the extra await
const collection = await client.db("feedback").collection("itinerary");
// perform actions on the collection object
client.close();
} catch (e) {
console.log(`Caught error`,e)
}
};
connect().then(() => {
console.log('handle success here');
}).catch((exception) => {
console.log('handle error here: ', exception)
})

failed to connect to xxxxx:xxxx in 150000ms node mssql

I have a node js job. This job is using node-cron to run some logic in every hour.
It's connecting to sql server database using node mssql package.
connection file code:
const sql = require('mssql');
const conn = (function () {
try {
return new sql.ConnectionPool(obj);
}
catch (err) {
throw err;
}
}())
const pool = (function () {
try {
return conn.connect();
}
catch (err) {
throw err;
}
}());
const myConn = async function getConn() {
try {
return await pool;
} catch (err) {
throw err;
}
};
module.exports = {
myConn
}
Code to call stored procedure:
async function callProc(procedureName, inputList, callback) {
try {
const pool = await connectionFile.myConn();
const request = new sql.Request(pool);
if (inputList) {
for (const param of inputList) {
request.input(param.name, param.type, param.value);
}
}
const result = await request.execute(procedureName);
callback(null, result);
}
catch (err) {
callback(err, null);
}
}
Intermittently my job is failing with error "failed to connection to in 15000ms"
Any suggestion?

Resources