Home > Software engineering >  Why "_db" variable is showing undefined?
Why "_db" variable is showing undefined?

Time:12-08

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';
};

  • Related