Having trouble connecting to MongoClient before calling MongoClient.prototype.db

(Before starting, I should note I am very new to MongoDB and using the drivers.)

Hello! I am receiving this error when trying to run my discord bot - or application, if you will.

MongoError: MongoClient must be connected before calling MongoClient.prototype.db

I’m not quite sure why this is. Originally, I thought it was simply not connecting fast enough before MongoClient was called, so I set it up on a VPS using Redhat with AWS. However, the error still persists, so I assume it has something to do with my code.

Here is the entirety of my code where the error lies:

require(“dotenv”).config({path: “path/to/.env”});

const uri = process.env.MONGOURL;

const MongoClient = require(“mongodb”).MongoClient;

const mongo = new MongoClient(uri, {

useNewUrlParser: true,

useUnifiedTopology: true

});

let bname = “Beyblade”

mongo.connect(err => {

console.log(“MongoDB connected for Beyblade.js”);

});

const ids = mongo.db(“main”).collection(“ids”)

const id = ids.find({});

const datas = {};

Promise.all([id]).then(data => {

let beys = data[0];

beys.forEach(bey => {

datas[bey._id] = {

  latest: bey.latest,

  name: bey._id

}

});

console.log(“Updated data!”);

});

setInterval(() => {

mongo.db(“main”).collection(“ids”).updateOne({_id: bname}, {$set: {latest: datas[bname].latest}});

}, 600000);

class Beyblade {

constructor(name, type, image, firstOwner, id){

this.name = name;

this.type = type;

this.image = image;

this.firstOwner = firstOwner;

this.level = 1;

this.xp = 0;

this.specials = [];

this.passives = [];

this.aliases = [];

this.gen = 1;

bname = name || this.name;

if(id) this.id = id;

else {

if(this.name !== "Buddy Bey"){

  if(datas[this.name]){

    this.id = datas[this.name].latest || 1;

    datas[this.name].latest = (datas[this.name].latest || 1) + 1;

  }else{

    mongo.db("main").collection("ids").insertOne({_id: this.name, latest: 2});

   datas[this.name] = {latest: 2};

   this.id = 1;

 }

ids.updateOne({_id: this.name}, {$set: {latest: datas[this.name].latest}});

}

}

}

async init(){

return true;

}

}

module.exports = Beyblade;

I hope you guys can help me out! Thank you in advanced!

Hello @Cringe_Burst, welcome to the MongoDB Community forum!

From your code:

const MongoClient = require("mongodb").MongoClient;
const mongo = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
mongo.connect(err => {
    console.log("MongoDB connected for Beyblade.js");

});
const ids = mongo.db("main").collection("ids")
const id = ids.find({});
// ...

The error is suggesting that the program is invoking the mongo.db("main") before the connecting to the server at mongo.connect(...). This is because of the way you have structured the code - the JavaScript coding. The program is trying something before completing something before that.

See the NodeJS Driver’s QuickStart and try the following sections, first:

  • Connection Guide
  • CRUD Operations

And, finally see the topic on Promises and Callbacks; knowing how to use these will solve your current problem.

For example, changing your code to this, will connect to the database, get an instance of the collection ids, runs the find method on the collection and prints the collection documents to the console.

mongo.connect(err => {
    console.log("MongoDB connected for Beyblade.js")
    const ids = mongo.db("main").collection("ids")
    ids.find({}).toArray(function(err, result) {
       // the variable result is an array of the documents, do something with them
       console.log(result)    // this will print the documents from the collection
    })
});

OK great, I changed it to this but now am receiving this error:
@Prasad_Saya

ReferenceError: mongo is not defined

Do you know why this might be the case?

You can try this code - it runs fine on my computer:

const MongoClient = require('mongodb').MongoClient;
const uri = 'mongodb://localhost:27017' // you substitute your uri value here
const mongo = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
mongo.connect(err => {
    console.log("Connected to MongoDB server...");
	const ids = mongo.db("testdb").collection("booksCollection") // substitute your database and collection names
	ids.find({}).toArray(function(err, result) {
        console.log("find query executed...")    
        console.log(result)
	});
});

It seems like it might work…but I am now encountering another error:

ReferenceError: ids is not defined

And here’s what I changed my code to (feel free to let me know if I did something wrong while changing it)

require(“dotenv”).config({path: “path/to/.env”});
const MongoClient = require(“mongodb”).MongoClient;
const uri = process.env.MONGOURL;
const mongo = new MongoClient(uri, {useNewUrlParser: true,useUnifiedTopology: true});
let bname = “Beyblade”

mongo.connect(err => {
console.log(“MongoDB connected for Beyblade.js”);
const ids = mongo.db(“main”).collection(“ids”)
ids.find({}).toArray(function(err, result) {
console.log(“find query executed…”)
console.log(result)
})
});

const id = ids.find({});
const datas = {};

Promise.all([id]).then(data => {
let beys = data[0];

I should also mention I am fairly new to JavaScript. I know it doesn’t completely relate to mongodb, but it’s very important for me to get it figured out. I will say that I truly appreciate you helping me a ton with my project!

Ok so SORRY so much for the amount of replies…
I figured out why it wasn’t working - ids is within the listener while the rest of my code is not. But, I need the rest of my code to be outside the listener so that I can run

module.exports = Beyblade;

…which is very important to be able to do. It’s not really mongodb related now, but I would appreciate it if you could help out? I really appreciate it! (No I really do, it means a lot that you’re helping me!!)~~

I think I need something like a global variable - I think that’s what it’s called.

It is related to the JavaScript programming topic Promises and Callbacks. It is important to understand the programming with these, as the MongoDB NodeJS driver API methods return callback or promise, in general. So, the steps in your program working with MongoDB will be associated with these concepts. There is no other way (I suspect).

I suggest you try the examples in the MongoDB NodeJS Driver documentation and adapt them to your own app.

Another useful source for callaback and promise programming is the MDN’s Introducing asynchronous JavaScript.