I am trying to connect to mongodb. I have just started web development.
Here is my database.js code:
const mongodb= require('mongodb');
const MongoClient = mongodb.MongoClient;
let _db;
const mongoConnect= callback=>{
MongoClient.connect('mongodb srv://pawan:*************@cluster0.vchvo.mongodb.net/myFirstDatabase?retryWrites=true&w=majority')
.then(client=>{
console.log('connected');
_db= client.db();
callback();
})
.catch(err=>{
console.log(err);
throw err;
})
}
const getDb=()=>{
if(_db){
return _db;
}
throw 'no database found';
};
exports.mongoConnect= mongoConnect;
exports.getDb= getDb;
(I have changed password to ******** only for the question)
Here is the Product.js(model) code
const mongodb = require('mongodb');
const getDb = require('../Util/database').getDb;
class Product {
constructor(title, price, description) {
this.title = title;
this.price = price;
this.description = description;
}
save() {
const db = getDb();
return db.collection('products')
.insertOne(this)
.then(result=>{
console.log(result);
})
.catch(err=>{
console.log("error from save in model" err);
})
}
}
module.exports= Product;
Upon running my node application I am able to view "connected" on my console. When after the line _db= client.db();
I do console.log(_db)
I get result as [Object Object]
but when I call _db
in the save() method of product.js model to establish connection
I get its value as undefined
due to which I get the final result as no database found
Please guide me so that I could find out what I am missing?
CodePudding user response:
It appears, that a small typo is the problem. You have to change a require
statement in the app.js
. Change this:
const mongoConnect = require('./util/database').mongoConnect;
to
const mongoConnect = require('./Util/database').mongoConnect;
Do you see the uppercase U
?
Explanation
When importing ./util/database
and ./Util/database
(note the uppercase U
) then node
treats these files as different because the path is not exactly the same. Windows does actually point to the exact same file, but the nodejs
cache treats them as different files why the file gets executed twice and your _db
variable is actually newly declared in the second call.
This is a very confusing problem which only happens on windows.. Linux for example would treat these paths as differently! .
Showcase
Here's an example what shows the problem exactly.
value.js
var value = 'NOT SET'
function setContent(_value) {
value = _value
}
function getContent() {
return value
}
exports.setContent = setContent
exports.getContent = getContent
And index.js
var { setContent } = require('./value')
setContent('New Value')
// import from same file, using the exact same path as setCOntent
var lowerCase = require('./value').getContent
// Note the uppercase "V" within the require.
var upperCase = require('./Value').getContent
console.log('LowerCase Import value (correct import.):', lowerCase())
console.log('UpperCase Import value (false import.):', upperCase())
output
LowerCase Import value (correct import.): New Value
UpperCase Import value (false import.): NOT SET
As you can see, the same file will be executed twice for different file paths. Maybe someone can try on linux? If it is the same behaviour?
CodePudding user response:
Your _db
variable inside getDb()
will always be undefined
. I cannot exactly explain to you why, maybe some more experience JavaScript guru will come along to do that. I'd be curios to learn why that is exactly.
But to get it working you could simply wrap your DB in an object to allow keeping the reference around inside getDb
:
const _db = { value: null };
...
MongoClient.connect('mongodb srv://pawan:*************@cluster0.vchvo.mongodb.net/myFirstDatabase?retryWrites=true&w=majority')
.then(client=>{
console.log('connected');
_db.value = client.db();
callback();
})
...
const getDb=()=>{
if(_db.value){
return _db.value;
}
throw 'no database found';
};