简体   繁体   中英

failing to create mongodb connection in nodejs 8

Nodejs : v8.11.3 - mongo : v3.6.3

following tutorial http://mongodb.github.io/node-mongodb-native/3.0/tutorials/crud/

app.js

const mongoDB = require('./common_mongo.js')
mongoDB.initMongo()

common_mongo.js

const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
const dbName = 'onthemove';

let getDb;
const initMongo = async () => {
    const client = await MongoClient.connect(url);
    getDb = await client.db(dbName);
    await getDb.collection('comments').insert({text: 'hello'});
    //WORKS
};

module.exports = {
    initMongo,
    getDb,
};

user.js

const mongoDB = require('./common_mongo.js');

app.get('/users', async (req, res) => {     
    let list  = await mongoDB.getDb.collection('user').find({})
    //FAILS
    res.send(list);
})

TypeError: Cannot read property 'collection' of undefined in user.js

Note : I have tried this earlier with lower versions it used to work ,but with there new versions im facing problem.

You have user.js loaded prior to initMongo actually occurs. So the mongoDB will hold undefined value for the getDb variable.

Simplest possible way to refactor this would be to just change getDb from variable to function so your code will look similar to this:

common_mongo.js

const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
const dbName = 'onthemove';

let db;
const initMongo = async () => {
    const client = await MongoClient.connect(url);
    db = await client.db(dbName);
    await db.collection('comments').insert({text: 'hello'});
};

module.exports = {
    initMongo,
    getDb() {
      return db;
    },
};

user.js

const mongoDB = require('./common_mongo.js');    

app.get('/users', async (req, res) => {     
    let list  = await mongoDB.getDb().collection('user').find({})
    res.send(list);
})

even further you can define a getter instead of the getDb

module.exports = {
    initMongo,
    get db() {
      return db;
    },
};

app.get('/users', async (req, res) => {     
    let list  = await mongoDB.db.collection('user').find({})
    res.send(list);
})

You need to initialise before using getDb , following code may help you

const mongoDB = require('./common_mongo.js');

app.get('/users', async (req, res) => {   
    if (!mongoDB.getDb) {  //Check getDb initialise or not
        await mongoDB.initMongo();
    }
    let list  = await mongoDB.getDb.collection('user').find({})
    //FAILS
    res.send(list);
})

You have declared initMongo as an asynchronous function. When you call initMongo it just returns a promise and the program flow continues. In that case getDb is not initialized yet. You can wait until the promise is fulfilled or an error occurrs:

mongoDB.initMongo().then(function () {
    // connection succeeded. Do the stuff from user.js
}).catch(function (err) {
     //failure callback. Doing the stuff from user.js won't make any sense here.
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM