Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if document exists in mongodb using es7 async/await

I'm trying to check if the user with the email provided exists in the collection users, but my function keeps returning undefined for every call. I use es6 and async/await in order to get rid of lots of callbacks. Here's my function (it is inside of a class):

async userExistsInDB(email) {
    let userExists;
    await MongoClient.connect('mongodb://127.0.0.1:27017/notificator', (err, db) => {
        if (err) throw err;

        let collection = db.collection('users');

        userExists = collection.find({email: email}).count() > 0;
        console.log(userExists);

        db.close();
    });
    console.log(userExists);
    return userExists;
}

So, the first console.log inside the .connect call always returns false because the returned value of the .find is not an array, it is some huge object which looks like this:

{ connection: null,
  server: null,
  disconnectHandler: 
   { s: { storedOps: [], storeOptions: [Object], topology: [Object] },
     length: [Getter] },
  bson: {},
  ns: 'notificator.users',
  cmd: 
   { find: 'notificator.users',
     limit: 0,
     skip: 0,
     query: { email: '[email protected]' },
     slaveOk: true,
     readPreference: { preference: 'primary', tags: undefined, options: undefined } },
  options: 
........
........

And the last console.log is always undefined (although I think it shouldn't be like that, because await waits for the end of the asynchronous call, right?)


I just need my function to return a boolean value, not a Promise or something.

Can anybody help me with that?

UPDATE 1

console.log(collection.findOne({email: email})); inside the .connect returns this:

 { 'Symbol(record)_3.ugi5lye6fvq5b3xr': 
   { p: [Circular],
     c: [],
     a: undefined,
     s: 0,
     d: false,
     v: undefined,
     h: false,
     n: false } }

UPDATE 2

Seems like it was the issue with my poor knowledge of es7 async/await.

Now the code inside the .connect returns the needed value.

async userExistsInDB(email) {
    let userExists;
    await* MongoClient.connect('mongodb://127.0.0.1:27017/notificator', async(err, db) => {
        if (err) throw err;

        let collection = db.collection('users');
        userExists = await collection.find({email: email}).limit(1).count() > 0;

        db.close();
    });
    console.log(userExists); // <--- this is not called at all
    return userExists;
}

However, now the console.log or anything after the .connect call is not performed at all.

Now, every time I call the userExistsInDB() function somewhere and console.log its result, I get this:

 { 'Symbol(record)_3.78lmjnx8e3766r': 
   { p: [Circular],
     c: [],
     a: undefined,
     s: 0,
     d: false,
     v: undefined,
     h: false,
     n: false } }

Any ideas why it is like that?

like image 449
Denis Yakovenko Avatar asked Oct 31 '15 10:10

Denis Yakovenko


1 Answers

Ok, here's how I got it working:

async function userExistsInDB(email, password) {
    let db = await MongoClient.connect('mongodb://127.0.0.1:27017/notificator');
    try {
        let collection = db.collection('users');
        let userCount = (await collection.find(
            {
                email: email,
                password: password
            }).limit(1).count());
        return userCount > 0;
    } finally {
        db.close();
    }
}

And because the async keyword in function declaration guarantees that the returned value will be a Promise, the only way to get the real returned result out of this function is:

let result = await this.userExistsInDB(email, password); inside of another function declared async.

like image 55
Denis Yakovenko Avatar answered Sep 18 '22 14:09

Denis Yakovenko