1

I am using a library that requires me to pass in a "validate" function. In this function I need to validate some input and then return true if it passes or false if it fails.

The problem is that I need to check if a user exists in the database for this validation function and Mongoose invokes a callback with the result. If I return within the callback it's just returning from the callback function not my validate function.

...
validate: function (username) {
    User.findOne({ username: username }, function (err, user) {
        if (user)
            // User exists so we should return false from the validate function
        else
            // User does not exist so we should return true from validate.
    });
}

I'm trying to use the async library to solve this, but async also invokes a callback when its done!

1
  • round peg in a square hole, won't work. you can fake async, but you can't fake sync. Commented Sep 26, 2013 at 20:28

2 Answers 2

2

Short answer: You can't.

For all intents and purposes JavaScript is single-threaded. Yes, you have callbacks and presence of multi-threading (setTimeout, setInterval, event callbacks) but you can't jump out of a callback and come back in the same function.

My advice is to try to pre-process this validation before validate is called so you have a "yay or ney" result to work within within validate.

Sign up to request clarification or add additional context in comments.

2 Comments

Dang. I don't have the value to search for in the database until this function is called. In what way should the library be modified so that this work can be done? I will modify it and submit a pull request if I can but I'm not sure how I would change this behavior. Should one of the arguments passed to the validate function be a done callback or something?
I don't know the work-flow, but you either perform the lookup while (or just after) the value is being changed (so at time of validation you have a checksum value), or introduce a pre-step that the user needs to execute before validate is available. (I know you're in node, but a for instance would be the submit button isn't enabled until the user presses "check" next to the username field)
0

You can use promises to achieve this.

var q = require('q');

validate: function (username) {
    var deferred = q.defer();
    User.findOne({ username: username }, function (err, user) {
      if (err){return deferred.reject(err)}
      if (user)
        // User exists so we should return false from the validate function
        deferred.resolve(false);
      else
        // User does not exist so we should return true from validate.
        deferred.resolve(true)
    });
    return deferred.promise;
 }

and then use the validate function as below.

validate('username').then(function(result){
  if (result)
     console.log('user doesnt exist');
  else
     console.log('user exists');

}, function(err){
   if(err)
      console.log('Error', err); 
})

1 Comment

I can't return a promise. The library expects true or false to be returned from the validate function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.