Denis Yakovenko Denis Yakovenko - 8 months ago 128
Node.js Question

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@example.com' },
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?

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download