0

So, when I first open the connection with the database, all is working fine, but when I close it and try to re-open it, the db object gives no error but returns undefined ...

Here's how I open the connection :

let conn = null;
let db = null;

async function validateLoginForm(payload, res) {
    const errors = {};
    let isFormValid = true;
    let message = '';

    if (!payload || typeof payload.email !== 'string' || payload.email.trim().length === 0) {
        if (payload.email !== 'anonymous') {
            isFormValid = false;
            errors.email = 'Please provide your email address.';
        }
    }

    if (!payload || typeof payload.password !== 'string' || payload.password.trim().length === 0) {
        if (payload.email !== 'anonymous') {
            isFormValid = false;
            errors.password = 'Please provide your password.';
        }
    }

    let stringConnection = payload.email === 'anonymous' ? 'mongodb://ds133221.mlab.com:33221/sandbox-te' : 'mongodb://' + payload.email + ':' +
        payload.password + '@ds133221.mlab.com:33221/sandbox-te';

    conn = await MongoClient.connect(stringConnection, await function(err, dbase) {
        if (err)
        {
            isFormValid = false;
            let errorMessage = 'Error connecting to DB';
            return res.status(400).json({
                success: false,
                message: errorMessage,
                errors: errors
            });
        }
        else
        {
            db = dbase;
            if (payload.email !== 'anonymous')
            {
                let roles = dbase.command({usersInfo: {user: payload.email, db: 'sandbox-te'}, showCredentials: true}, (err, result) => {
                    if (result.users[0] && result.users[0].roles[0] &&
                        (result.users[0].roles[0].role === 'dbOwner' || result.users[0].roles[0].role === 'readWrite'))
                    {
                        dbase.close();
                        return res.status(200).json({
                            success: true,
                            hasWriteRole: true
                        })
                    }
                });
            }
            else
            {
                return res.status(200).json({
                    success: true,
                    hasWriteRole: false
                })
            }
        }
    });
}

The first part of the file validates a login form and the second part uses the email and password to try to open a connection with the database.

The whole function just works fine, but when I try to re-open it in the same file but another function, it won't work :

router.post('/search', (req, res) => {

    db.open((err, dbase) => {
        let test = dbase.collection('test');
        console.log(test);
        let promiseOfFind = test.find({}).toArray((err, docs) => {
            console.log(docs);  // RETURNS UNDEFINED ONLY IF DB WAS CLOSED EARLIER
        })
    });
});

If I don't close the database in the validateLoginForm function, I can retrieve documents without having to open it again, but I just want to achieve this..

What is wrong with my code ? I'm pretty new to Javascript and the API reference of the official MongoDB driver for node.js doesn't help much..

I'm using latest versions of React, Express, MongoDB official Driver for Node.JS, and of course, Node.JS

Thanks in advance !

5
  • Because you have an argument on the "left hand side" asking for a "Promise". Make up your mind if you want a "Promise" or a "Callback". Commented Jul 19, 2017 at 9:36
  • Also, I don't know what you are reading but db.open() looks like you are trying to access a deprecated method. The connection should always be open. Commented Jul 19, 2017 at 9:38
  • Reading this : mongodb.github.io/node-mongodb-native/2.2/api/Db.html#open which is the official documentation for the 2.2 driver. I'm using the 2.2.29. Also, your first comment didn't solved the issue. Commented Jul 19, 2017 at 9:41
  • Nope. MongoClient all the way. Has been that way for years. As for "solve the issue" your code has lots of problems and not just one. That documentation is actually very helpful when you take the time to read it. There are plenty of very clear usage examples. None of them try to invoke a promise and a callback at the same time. Commented Jul 19, 2017 at 9:42
  • I've not been in Javascript for years, I'm still learning (and for someone that comes from Software development, I'm a little lost I have to admit).. But thanks for your comment, guess I'll have to skip this API documentation then. Also, I answered agressively because you did in the first place. I'm here to seek advice (I don't ask for code), not to be burnt. Finally, the doc. of db.open doesn't give any exemple code (it's db.on() in the exemple, which doesn't exists). Commented Jul 19, 2017 at 9:44

1 Answer 1

1

With MongoDB you should open a single connection and re-use it through your application. You don't need the promises you've got then.

So on startup:

const connection = MongoClient.connect(stringConnection, function(err, dbase) {
  // Start web server
});
Sign up to request clarification or add additional context in comments.

3 Comments

I indeed saw this here and there. I'm planning to do it, but is db.open() really impossible to achieve ? Thanks for your comment though ! :)
@GaetanBoyals You probably could, but I'd avoid using that approach as most people/Mongo themselves use the MongoClient. Check out university.mongodb.com/courses/M101JS/about for free training courses provided by Mongo
Thanks for the advices and the link, very helpful ! :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.