0

I have a file called extrafunctions.js that exports functions to be run by app.js. One of these functions includes the MongoDB query findOne. The problem is that the function returns a value before the query finishes and thus app.js doesn't get the needed data but instead "undefined".

I have tried Promises to some extent but haven't been able to get anything to work.

app.js:

const extraFunctions = require("./extraFunctions");
app.get('/api/login', (req, res) => {
    res.end(extraFunctions.login());
});

extraFunctions.js:

function login () 
{
client.connect(err => {
    var collection = client.db("site").collection("test");
    collection.findOne({}, (err, result) => {
        if (err) throw err;
        console.log(result);
        return result;

    });
    client.close();
}); 
}

module.exports.login = login;

Fixed Version Same as the accepted comment but had to change res(result) to res(JSON.stringify(result))

Ben Magill
  • 38
  • 3
  • 8
  • Possible duplicate of [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) – nicholaswmin Apr 07 '19 at 17:13

2 Answers2

0

you need to use promise or async-await, below is an example of promise implementation:

App js

const extraFunctions = require("./extraFunctions");
app.get('/api/login', (req, res) => {
    extraFunctions.login().then(result =>{
        res.end(result);
    })
});

extraFunctions.js

function login() {
    return new Promise((res, rej) => {
        client.connect(err => {
            if(err){
                rej(err)
            }
            var collection = client.db("site").collection("test");
            collection.findOne({}, (err, result) => {
                if (err) rej(err);
                console.log(result);
                res(result)
            });
            client.close();
        });
    })
}

module.exports.login = login;
kgangadhar
  • 4,886
  • 5
  • 36
  • 54
0

If you're using the native mongodb connector, then it provides Promise support. You can use like:

// connection is a promise
const connection = MongoClient.connect(url, { useNewUrlParser: true });

// async function
async function login () {
  let result;
  try {
    const client = await connection;
    var collection = client.db("site").collection("test");
    try {
      result = await collection.findOne({})
    } catch (err) {
      throw err;
    }
    client.close();
  } catch (e) {
    throw e;
  }
  return result;
}

module.exports.login = login;

In your route:

const extraFunctions = require("./extraFunctions");
app.get('/api/login', async (req, res, next) => {
  try {
    const result = await extraFunctions.login();
    res.end(result);
  } catch (e) {
    next(e);
  }
});
1565986223
  • 6,420
  • 2
  • 20
  • 33