1

I make a Vote App, now I try to check if the user already voted to current poll. My problem I think is a callback function that not work in the time I want. I try a lot of method and read a lot about the callback and synchronize functions, and still don't know how to fix this problem.
Now the code (all in same route post):

Here I find the poll that user vote:

Poll.findById(req.params.id,function(err, poll){     //Find the Poll
       if(err){
           console.log("Vote(find the Poll) post err");
        }
        var test = function(poll,req){                            //check if user already vote to the poll
                if(req.user.local){//if it`s auth user
                    console.log("test");
                    User.findById(req.user._id,function(err, userFound){
                        if(err){
                            console.log("[checkVoted] Error findById");
                        }
                    for(var i=0;i<userFound.local.vote.poll_voted.length;i++){//run on poll_voted array
                        console.log("test for");
                        if(poll._id == userFound.local.vote.poll_voted[i]){
                            console.log("**return 1**");
                            return 1;//User already voted to this poll
                        }
                    }//end for
                    console.log("test return 0");
                    return 0;//user not voted
                    });//end user find
                } else{ //anonmey user 
                    console.log("[checkVoted] ELSE!");
                    return false;
                }//else end
            };//function end

after I call to test function here:

 **if(test(poll,req))**{ //If user already voted, redirect
                console.log("already vote");
                res.redirect("/poll/"+poll._id);
            }**else**{//User not voted. 
                console.log("test Else not voted");
                User.findById(req.user._id, function(err, user) {//find the id and save in voted poll
                    if(err){
                        console.log("[VOTE>POST>User.findByID ERROR");
                    } else{
                        user.local.vote.poll_voted.push(poll._id); 
                        user.save(function(err){
                        if(err){
                            console.log("save user._id in poll_voted ERORR");
                        }});
                    }});//end User.findById
                var options = poll.options;
                var optionIndex = _.findIndex(options,["id", req.params.option_id]);
                poll.options[optionIndex].vote++;
                poll.save(function(err){
                if(err){
                   console.log("save vote error");
                } else{
                   res.redirect("/poll/"+poll._id);
                }
            });
        }//end of else
    });//end of Poll findById

Now the user choose the options and vote, its enter to function and log the "return 1" (marked), but it's not enter to the IF (marked) and ofcurse to the else (makred)...what I do wrong?

EDIT: i try this method ,from the log it`s work but i have antoher error now: EDIT 2: SOLVED.this code:( Thanks all)

router.post("/poll/:id/:option_id", function(req, res){
   Poll.findById(req.params.id,function(err, poll){     //Find the Poll
       if(err){
           console.log("Vote(find the Poll) post err");
        }
        var test = function(poll,req, callback){
                var flag=0;
                if(req.user.local){//if it`s auth user
                    console.log("test");
                    User.findById(req.user._id,function(err, userFound){//look for id user
                        if(err){
                            console.log("[checkVoted] Error findById");
                            }
                        for(var i=0;i<userFound.local.vote.poll_voted.length;i++){//runnig on poll_voted array
                            console.log("test for");
                            if(poll._id == userFound.local.vote.poll_voted[i]){
                                console.log("**return 1**");
                                flag=1;//User already voted to this poll
                            }
                        }{//end for
                    console.log("test return 0");
                    callback(flag);
                    }});//end user find
                }//end if auth user
            };//test function end
            test(poll, req, function(param){
                if(param){
                    console.log("already vote");
                    res.redirect("/poll/"+poll._id);
                } else{
                    console.log("test Else not voted");
                    User.findById(req.user._id, function(err, user) {//find the id and save in voted poll
                        console.log("user findbyid succes");
                        if(err){
                            console.log("[VOTE>POST>User.findByID ERROR");
                        } else{
                            console.log("user findbyid succes else");
                            user.local.vote.poll_voted.push(poll._id); 
                            user.save(function(err){
                                if(err){
                                console.log("save user._id in poll_voted ERORR");
                            }});
                    }});//end User.findById
                    console.log("user save the vote start");
                    var options = poll.options;
                    var optionIndex = _.findIndex(options,["id", req.params.option_id]);
                    poll.options[optionIndex].vote++;
                    poll.save(function(err){
                    if(err){
                        console.log("save vote error");
                    } else{
                        console.log("user save the vote finsh");
                        res.redirect("/poll/"+poll._id);
                    }});
                }});
            });
});
Error: Can't set headers after they are sent
Naor Malca
  • 143
  • 1
  • 10
  • 2
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Yury Tarabanko Sep 04 '17 at 08:09
  • thank you but i read this article,try some method there but still now work. – Naor Malca Sep 04 '17 at 08:10
  • Then you should read it again. You are still trying to return from async call which doesn't make sense. – Yury Tarabanko Sep 04 '17 at 08:11
  • All the examples not same like my issue,i try to run a function that return a value to IF ,where i locate the callback if the function do one thing?@YuryTarabanko – Naor Malca Sep 04 '17 at 08:56
  • 1
    "the examples not same like my issue" - yes they are. "i try to run a function that return a value " you can't return a plain value from **async** function. For example you could add a `callback` param to your test function and move entire `if` into the callback. Or familiarize yourself with Promises to avoid callback hell. – Yury Tarabanko Sep 04 '17 at 09:01
  • test(poll,req,function{if()}) you mean to this? if yes ,it`s return true or false before its move to the callback,i want that the result from test will checked by the IF ,sorry but i still not get it.... – Naor Malca Sep 04 '17 at 09:24

1 Answers1

1

test(poll,req) is a synchornous function but inside it there is an asynchronous reference to function User.findById(req.user). One option would be to pass a callback function


    test(poll,req, function(param){
        ... process return values from callback
        .... if case validations
    })

and call it in


    var test = function(poll,req, cb){  
        User.findById(req.user._id,function(err, userFound){
            if(err){
                console.log("[checkVoted] Error findById");
            }
            ...for loop
            cb(param)
        }
    }

ralixyle
  • 754
  • 1
  • 7
  • 18