Abhishek Pathak Abhishek Pathak - 2 months ago 17
Javascript Question

Calling an async JS function within if condition

I want to generate a unique token, so I have to check if the token value already exists in the MongoDB database. I am checking inside if condition if the token already exists. Though in development mode I have only a few tokens in the database, so the random value must be generating something different, but once in production, there will be many token.

My question is will the if condition wait for database to query and return output from

alreadyExists
function below? Or being async, it will move down and
generateToken()
again?

Here is the code,

//Function to check if string already exists
function alreadyExists(val) {
doc.findOne({token: val}).exec(function(err, docObj){
if(!docObj) return 0; //If token not found, send a false
else if (err) return 1; //If error or token, send a false value
else return 1; //If token found, send a true value
});
}

//Function to generate a random token
function generateToken() {
var t = Math.floor(((Math.random() * 9) + 1.111)*1000); //Generates number between 1000 and 9999
if(!alreadyExists(t)) //Check if token not already exists
return t; //Return the token
generateToken(); //Call recursively again until unique token is generated
}


Also, is the code for random correct? I have to generate number actually in between 1111 and 9999 (excluding range end, though including is also fine)

Answer Source

You should look more into Javascript Promises if you want to call an synchronous function. Right now your function will already return undefined in an if statement, because it did not have time to execute, aka making your if statement always if (!false), as undefined is falsy.
Wrap your other function in a promise and use .then() notation to catch the value.

function alreadyExists(val) {
  return new Promise((resolve, reject) => {
    doc.findOne({token: val}).exec(function(err, docObj){
      if(!docObj) resolve(0); //If token not found, resolve falsy value
      else if (err) reject(err) //If error reject
      else return resolve(1); //If token found, resolve truthy value
    });
  });
}

//Function to generate a random token
function generateToken() {
  var t = Math.floor(((Math.random() * 9) + 1.111)*1000); //Generates number between 1000 and 9999
  alreadyExists(t)
  .then((value) => {//.then() waits for promise to resolve
    if(!value){ //Check if token not already exists
      return t; //Return the token
    }else{
      generateToken(); //Call recursively again until unique token is generated
    }
  })
  .catch((err)=>{
    console.log("Error:",err) //catch any thrown errors
  })
}