user6043537
user6043537

Reputation:

node js callback as var

Am trying to create a method that i can call from all parts of my express app, i simply pass a value to this method and it searches through mongodb using moongose to see if user exists, then it returns a Boolean as result.

function findUserExists(name){

 User.findOne({ "name": name }, function(err, user) {

 if (user){ 
    console.log("user exits");
    return true;
 }
 else{ 
        console.log("user not exits");
    return false; }
});

Now when i call it in another method like this, it doesn't return the Boolean value in time.

if (findUserExists("username")){

// redirect to dashboard
console.log("user exits");
    res.redirect('/dashboard');
}
else {
 // redirect to sign up page
console.log("user must sign up");
    res.redirect('/signup');
}

So in this case the other functions run before getting the Boolean value from the findUserExists(), my question is how can i make this function return a value before other functions run, in a way that i can call it in an IF condition or even a var like this

var exists = findUserExists(name);

Upvotes: 0

Views: 83

Answers (3)

Nidhin David
Nidhin David

Reputation: 2474

In your logic there is a problem, you are not handling errors that might occur in the query itself like DB server down. Avoid using callbacks as much as possible and switch to promises, async await, etc..

Using Promises:

If no call back is passed to Mongoose, then it will return a Promise. If query is successfull it will resolve with document. In this case if user does not exists, then it will be resolved with a null (link), if user exists then it will be resolved with that document. In case if query fails, for example DB server unavailable etc, then the promise will be rejected with an err object.

DB call

  function findUserExists(name){
    return User.findOne({ "name": name })
    .then(function(doc){//This function will be executed if DB query was successful.
      //You can write additional logic if any to handle the returned doc here
      return doc;
    }, function(err){// This function will be executed if something goes wrong with db server or query.
      //You can write logic for error handling in DB connection like logging DB failure.
      return err;
    })
  }

Validation:

findUserExists(name)
.then(function(user){//Resolved callback: This function is executed if previous promise was resolved
  if(!user){ //If user does not exist null will be returned
    console.log('User must sign up');
    return res.redirect('/signup');
  }
  console.log('User Exists');
  return res.redirect('/dashboard');
},function(err){ //This function is executed if previous promise is rejected
  console.log('Some error occurred in DB query');
})

Upvotes: 2

Everettss
Everettss

Reputation: 16029

You are trying to force synchronous code on asynchronous function. Short answer is: you shouldn't do this

Convert your function to callback

function findUserExists(name, callback) {
    User.findOne({ "name": name }, function (err, user) {
        callback(user);
    });
}

and then use as this:

findUserExists("username", function (exists) {
    if (exists) {
        console.log("user exits");
        res.redirect('/dashboard');
    } else {
        console.log("user must sign up");
        res.redirect('/signup');
    }
});

You can use promises to code look more synchronous if you use node 4 and above.

Upvotes: 4

leesio
leesio

Reputation: 741

This is because your findUserExists function calls an asynchronous but you're trying to use it synchronously.

In order to achieve what you're looking to do, you need to provide your function with a callback function or return a promise. The easiest way, since you're already using callbacks in mongoose would be like this:

    function findUserExists(name , callback ){
     User.findOne({ "name": name }, function(err, user) {
      if( err ) callback( err );
      else if (user){
        console.log("user exits");
        callback( null, true );
      }
      else{
        console.log("user does not exist");
        callback( null, false );
      }
    });

    findUserExists( "username", function( err, user ){
      if( err ) console.log( err );
      else if( user ){
        console.log("user exits");
        res.redirect('/dashboard');
        // redirect to dashboard
      }
      else {
       // redirect to sign up page
        console.log("user must sign up");
        res.redirect('/signup');
      }
    }

Upvotes: 1

Related Questions