Check if document exists in mongodb using es7 async/await
Asked Answered
O

1

12

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?

Otocyst answered 31/10, 2015 at 10:52 Comment(3)
Don't use count(), you are asking mongodb to go on counting even after first such document has been found. Just use findOne() and see if it returns anything with same email.Issacissachar
Please, see the update. BTW, I've read somewhere that using findOne() is way slower than using find().limit(1), what would you say about that?Otocyst
@Dennis find().limit(1).count() is indeed a good optimization. The JavaScript driver for mongo automatically does this in its findOne() implementation.Issacissachar
O
13

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.

Otocyst answered 2/11, 2015 at 7:37 Comment(1)
useful @note to self :)Xever

© 2022 - 2024 — McMap. All rights reserved.