-2

As I said, I want to create a function that have to arguments, username and email. If one of them is in the database, then user can't register.

function checkAll(username, email) {
  let num = 0;
  User.find({}, (err, result) => {
    if (err) throw err;
    for (let i = 0; i < result.length; i++) {
     if (username === result[i].username || email === result[i].email) {
        num++;
      }
    }
    db.close();
    if (num == 0) {
      return true;
    }
    return false;
  });
}

console.log(checkAll("test", "test@test.com"));

I know that User.find() is an asynchronous function that have a second arguments that it is a callback, but my question is: Why does it return undefined??

Matin
  • 66
  • 5

2 Answers2

0

The function checkAll finishes execution before the callback of the find operation is triggered, and since you aren't returning anything from checkAll, undefined is logged.

This should make it clearer :

function checkAll(username, email) {
  let num = 0;
  User.find({}, (err, result) => {
    console.log('here');
    if (err) throw err;
    for (let i = 0; i < result.length; i++) {
     if (username === result[i].username || email === result[i].email) {
        num++;
      }
    }
    db.close();
    if (num == 0) {
    console.log('now here');
      return true;
    }
    console.log('or mebbe here');
    return false;
  });
}

console.log(checkAll("test", "test@test.com"));

you will see undefined and then here and then now here OR or mebbe here

jagzviruz
  • 1,453
  • 12
  • 27
0

Your outer function checkAll returns undefined since it has no return statement. Only your inner function, the callback to your mongo query does. Because of the async nature of the query, you can't simply return true or false. Your options are basically thus:

Pass a callback (or two) to checkAll:

function checkAll(username, email, cb){ //...
function checkAll(username, email, cb_success, cb_fail){ //...

Where you call cb with true or false from within your query callback, sending execution back to the original callsite.

Use a promise:

function checkAll(username, email){
    return new Promise((resolve, reject)=> {
        User.find({$or: [{username}, {emai}]}, (err, result)=>{
            if(result) reject('User exists');
            else resolve('Username/ email free');
        });
    };
}

// Usage:
checkAll('alice', 'test@example.com').then(create_user, user_exists);

Where create_user is a function handles the success case and user_exists is a function that handles the failure case.

wbadart
  • 2,583
  • 1
  • 13
  • 27