Pawan
Pawan

Reputation: 857

Why "_db" variable is showing undefined?

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?

Upvotes: 0

Views: 211

Answers (1)

Silvan Bregy
Silvan Bregy

Reputation: 2734

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?

Upvotes: 2

Related Questions