-1

I'm bulding a node.js backend for a webapp and when i submit a form, i do various validations. One of them is to check if an invitation already exists with the same email address.(isUserAlreadyInvited function)

I created a function for this, however when i call this, i guess the response is not that fast and it just moves to the next statement even if the check returns true. How

    //Loop through emails one by one
    var emails_to_invite = ["test@test.com","invalid.com"];
    var response_items = [];
    async.each(emails_to_invite,
        function(email, callback){

            //Response item
            var response_item = {}
            response_item.email = email;                

            //Validate
            if(Joi.validate({ email: email }, apiSchema).error) {
                response_item.error = "not valid email";
                response_items.push(response_item); 
                callback();
            } else if(email == user.email) {
                response_item.error = "Sending an invitation to your own email is kinda dumb";
                response_items.push(response_item); 
                callback();
            } else if(isUserAlreadyInvited(email,user_id)) {
                response_item.error = "already invited";
                response_items.push(response_item); 
                callback();
            } else {
                sendInvitationEmail(email,user_id,null,null,function(invitation_code){
                    if(invitation_code) {
                        response_item.invitationCode = invitation_code;
                    } else {
                        response_item.error = "server error";
                    }
                    response_items.push(response_item);     
                    callback();     
                });
            };
        },
        function(err){

            //Return response
            res.status(200).send(response_items);

        }
    );  

    function isUserAlreadyInvited(email,invited_by) {
        User.findOne({
            email: email,
            invited_by: invited_by
        }, function(err, user) {
            if(err) {
                return false;
            } else {
                return true;
            }
        });

    }
passatgt
  • 4,234
  • 4
  • 40
  • 54
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Mike Cluck Apr 14 '16 at 21:34
  • This is not a great answer in my opinion so I'm writing it as a comment, but would else if(!(isUserAlreadyInvited(email,user_id))) instead of your else work? – Alden Be Apr 14 '16 at 21:41
  • @AldenBe No because `isUserAlreadyInvited` is an asynchronous function. See the question I linked to previously. – Mike Cluck Apr 14 '16 at 21:47

1 Answers1

0

Two returns here:

function isUserAlreadyInvited(email,invited_by) {
        User.findOne({
            email: email,
            invited_by: invited_by
        }, function(err, user) {
            if(err) {
                return false;
            } else {
                return true;
            }
        });

    }

are defined inside this function

    function(err, user) {
            if(err) {
                return false;
            } else {
                return true;
            }
        }

and have nothing with return value of isUserAlreadyInvited().

Apparently your isUserAlreadyInvited() is an asynchronous function that needs to be treated asynchronously - it shall get callback function as a parameter. That callback shall be invoked in place of that function(err, user) {}

c-smile
  • 26,734
  • 7
  • 59
  • 86