Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Node js function requires a return value but value comes from callback so cannot be returned

Node js function requires a return value but value comes from callback so cannot be returned

Problem

Apologies for the confusing title, I will attempt to explain

I am using node.js with express-form and the custom validation function like so:

app.post('/register', form(
    field("username").trim().required().custom(function(value) {
       //Works correctly
       if (!user.validUsername(value)) {
           throw new error("Invalid username");
       }

       //Does not work due to callback
       user.uniqueUsername(value, function(uniqueUsername) {
            if (!uniqueUsername) {
                //Not unique, throw error
                throw new Error("username is already taken");
                //Could be subsituted for return "whatever"; and it would still be the same problem
            }
        });
    }),
    registerAttempt);
};

// ...
//Example function for brevity  
user.uniqueUsername = function(username, callback) {
    User.findOne({username: username}, function(err, user) {
        if (err) { throw err; }
        callback(user === null);
    });
}

I need a way to restructure this so the .custom(function(value) { .. }) doesn't finish executing until I have received the Callback but I have no idea how I could do it, if at all.

EDIT: corrected error

Problem courtesy of: Sam

Solution

It looks like express-form doesn't support asynchronous validations, so the only way to that is implement custom middleware. It can look like this:

app.post('/register',
    function (req, res, next) { //here it goes
        user.uniqueUsername(req.body.username, function(uniqueUsername) {
            req.body.uniqueUsername = uniqueUsername; //we can't do anything about it yet
            next();
        });    
    },

   form(field('username').trim().required().custom(function(value) {
        if (!user.validUsername(value)) {
             throw new error("Invalid username");
        }   
   }),
   field('uniqueUsername').custom(function(value) {
        if (!value) {
             throw new Error("username is already taken");
        }   
   }),

   registerAttempt);

It can be used as generic workaround for express-form being unable to make async validations: we pull all the data we need in a separate middleware and inject it as new fields to be then validated by express-form.

Solution courtesy of: vkurchatkin

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Node js function requires a return value but value comes from callback so cannot be returned

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×