1

So I have two files, server.js and db.js Now Here is the code that I am having issue with :

server.js :
var DB = require('./db')
app.get("/test", (req, res) => {
console.log(DB.getPostAll())
})

db.js :
MongoClient.connect(uri, { useNewUrlParser: true })
.then(function (db) {
    console.log("Connected")
    var dbo = db.db('test')

    module.exports.getPostAll = function getPostAll() {
        return (
            dbo.collection('posts').find({}).toArray(function (err, res) {
                if (err) throw err;
                else return res
            })
        )
    }
})
.catch(function (err) {

})

Sorry for the silly question. But can anyone say what am I doing wrong here ? I am trying to use two returns. Before this I tried to use a variable in place of the returns in db.js's getPostAll. But it also returns undefined.

Sagnik Pradhan
  • 509
  • 1
  • 5
  • 16
  • For part of your issue, read [How do I return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call/14220323#14220323) – jfriend00 Sep 02 '18 at 08:57

2 Answers2

2

There are plenty of bad practices in the code, I'll try to cover some.

  1. Your db.js file triggers an asynchronous action the moment it is required.
  2. You are not returning the Promise from the db.js file, hence your server.js file starts executing code without knowing if the connection to the DB was fulfilled/pending or rejected
  3. You are exporting a method after a function is executed, this leads to many odd and unexpected side effects. It is best to define all your exports at the top level of the file.

The simplest way to solve your issue is:

server.js :
const connectDB = require('./db')
connectDB().then((db) => {
   app.get("/test", (req, res) => {
      console.log(db.getPostAll())
   })
   app.listen(...); // lift the server ONLY when the db is connected
});

db.js :
module.exports = function connectDB() {
   return MongoClient.connect(uri, { useNewUrlParser: true })
   .then(function (db) {
       console.log("Connected")
       var dbo = db.db('test')
       return {
          getPostAll() {
             return dbo.collection('posts').find({}).toArray()
          }
       }
  })
}

In the db.js file, I am exporting a function that returns a promise, this way I can tell when the connection is complete (by having the promise resolved), it returns an object with all the db methods you need (getPostAll).

In the server.js file, I am waiting for the async connection to be established before I lift the app, this way I know i have my application in a ready state when it is served, and I have the db methods readily available for my app.

Bamieh
  • 10,358
  • 4
  • 31
  • 52
1

You are getting undefined as your promise has not resolved. Try using an async function and await your db operation to finish. See working with async funtions . you can also try mongoose object modeling as your mongodb client.

james gicharu
  • 99
  • 2
  • 7