Andre Hofmeister
Andre Hofmeister

Reputation: 3416

Check if user already exist and wait for callback

I have a small function to validate the user input. In that function I will also check if the email address is already taken. But I have some trouble with the async callback. I hope anyone could give me a hint, how I could solve this. I use nodejs with the express 3 framework, mongodb and the node-validator library.

This is a part of my validation function:

function check(data, callback) {
    mongoose.model('User', User).count(data, function (err, count) {
        callback(err, !! count);
    });
};

function validate(email, password, confirm) {
    var v = new Validator(),
        errors = new Array();

    v.error = function (msg) {
        errors.push(msg);
    };

    check({email: email}, function (err, exists) {
        v.check(exists, { email: 'E-Mail is already taken' }).equals(false);
    });
    ...
    return errors;
}

Based on the async callback the variable errors is at the return statement empty. How could I else check if the email address is already in the databse?

Upvotes: 0

Views: 3165

Answers (2)

7zark7
7zark7

Reputation: 10145

You need to think async and pass callbacks that will be called asynchronously. Quick example:

app.get('/blah', function(req, res) {
   // Whatever
   validate(email, pass, confirm, function(errors) {
     if (errors.length == 0)
         resp.send(200, 'blah');
     else
         resp.send(400, 'blah blah');
   });
})

function validate(email, password, confirm, callback) {
    var v = new Validator(),
        errors = new Array();

    v.error = function (msg) {
        errors.push(msg);
    };

    check({email: email}, function (err, exists) {
        v.check(exists, { email: 'E-Mail is already taken' }).equals(false);
    }, function() {
        callback(errors);
    });
    // ...
    return errors;
}

Upvotes: 2

Jacob
Jacob

Reputation: 3639

You are going to have to add a callback to your validate function. As it stands now, your check function is asynch so you are immediately returning the empty errors array.

function check(data, callback) {
    mongoose.model('User', User).count(data, function (err, count) {
        callback(err, !! count);
    });
};

function validate(email, password, confirm, callback) {
    var v = new Validator(),
        errors = new Array();

    v.error = function (msg) {
        errors.push(msg);
    };

    check({email: email}, function (err, exists) {
        if (err) {
            return callback(err);
        }

        v.check(exists, { email: 'E-Mail is already taken' }).equals(false);
        callback(null, v);
    });
};

// Calling to validate example
server.get("/validate_user_or_whatever", function(req, resp) {
    // Call validate with callback
    validate(req.param("email"), req.param("password"), true, function(err, validator) {
        if (err) {
            return resp.json({success: false, message: err.message});
        }

        var success = validator.isValid; // or something

        // Respond with the results
        resp.json({success: success});
    });
});

Now, your next question is probably going to be how do I run all these validate functions and wait for them to return before calling the validate callback. Good question, take a look at the async module.

Upvotes: 4

Related Questions