MongoExpiredSessionError: Cannot use a session that has ended - node.js

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.

Related

Type Error: Cannot read property 'collection' of null

Here is my code
//--conection.js--//
const mongoClient=require('mongodb').MongoClient
const state={
db:null
}
module.exports.connect=function(done){
const url='mongodb://localhost:27017'
const dbname='shopping'
mongoClient.connect(url,(err,data)=>{
if(err) return done(err)
state.db = data.db(dbname)
done()
})
}
module.exports.get=function(){
return state.db
}
//--helpers.js--//
var db=require('../config/connection')
module.exports={
addProduct:(product,callback)=>{
console.log(product);
db.get().collection('product').insertOne(product).then((data)=>{
console.log(data)
callback(data.insertdld)
})
}
}
This is the code I have written, please help me to find the solution and it is is showing this error "Cannot read property 'collection' of null"..
Your mongo instance is null. This way worked for me
async function main(){
const uri = "mongodb://localhost:27017/shopping";
const client = new MongoClient(uri);
try {
await client.connect();
await listDatabases(client);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
main().catch(console.error);

mongodb method without function not working in nodejs

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();
}
}

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)
})

How to return ctx in mangodb

I'm trying Koa instead of express and I have a problem returning ctx.
Here is my code :
router.get("/user/:id", async (ctx, next) => {
mongodb.connect(url, { useNewUrlParser: true }, (err, db) => {
if (err)
throw ("error => " + err);
else {
var dbo = db.db("test");
dbo.collection("users")
.find({})
.toArray((err, res) => {
if (err)
throw ("error => " + err);
db.close();
console.log(res);
ctx.body = {
"message": "GOT IT"
}
})
}
});
});
The problem is that ctx is unknown in the callback.
Any idea on how I can put it into the callback?
btw res is filled properly.
Thanks for help!
Maybe the problem with the callback has to do that you first have to wait for the
dbo.collection("users").find({})
And the do
toArray()
I use the koa-mongo library.
This library inject mongo into the context.
Open and close mongodb connection is not needed.
server.js
import Koa from 'koa'
import Mongo from 'koa-mongo'
const app = new Koa()
app.use(new Mongo(dbConfig))
In the router
let db = ctx.mongo
const result = await db.collection("users").find({})
if (!result) {
return []
}
return result.toArray()

Resources