0

So I have this MEAN-stack app where, on the back-end, I have two ways to create a new user: through google authentication and through username.

Now, I am working on the code to create a new user through username, but I can't return the value from another function in my node.js file (in this case createNewUser()). When I look at my database the new user is created, but the value returned from createNewUser() is undefined.

I first thought it was a problem due to asynchronicity, so I tried a setTimeout(). The function however still returns undefined. Does someone see why?

This is the route in my node.js backend: the two console.logs return undefined

router.post('/signup', function(req, res){


    var result = createNewUser(req.body);
    console.log('result 1', result);
    setTimeout(function(){
        console.log('result2', result);
        if (!result.success){
            res.status(500).json({
                message: "unable to create User",
                obj: result.err
            })
        } else {
            res.status(200).json({
                message: "successfully created new user",
                obj: result.obj
            })
        }
    }, 6000);

});

This is the createNewUser() function in that same file, the console.log returns the user, so the user is actually created, the function just doesn't return the value.:

function createNewUser(userData, socialRegistry){

    var user;

    if (socialRegistry){
        user = new User({
            firstName: userData.firstName,
            lastName: userData.lastName,
            email: userData.body.email,
            googleID: userData.body.provider.ID
        });
    } else {
        user = new User({
            firstName: userData.firstName,
            lastName: userData.lastName,
            username: userData.username,
            password: bcrypt.hashSync(userData.password, 10),
            email: userData.email,
            registerDate: new Date()
        });
    }

    user.save(function(err, user) {
        if (err) {
            return {
                success: false,
                err: err
            }
        }
        if (socialRegistry){
            return user
        } else {
            console.log(user);
            var test = {
                success: true,
                obj: user
            }

            return test
        }
    });
}
tilly
  • 2,229
  • 9
  • 34
  • 64
  • 3
    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) – ponury-kostek May 11 '18 at 16:13

1 Answers1

1

Although I agree that this is a basic Async issue, the link prescribed above answers it in a very general way, and is frankly TLDR for this issue here.

Since your processes, like save, are asynchronous, you can't just return something back. Instead, pass a closure / function to the code, and call that function when things have completed. Most of Node is predicated on this kind of usage, for reasons that are TLDR to list here.

createNewUser(req.body,null,function(result){
    if (!result.success){
            res.status(500).json({
                message: "unable to create User",
                obj: result.err
            })
        } else {
            res.status(200).json({
                message: "successfully created new user",
                obj: result.obj
            })
        }
});

function createNewUser(userData, socialRegistry, onComplete){
 ....
    user.save(function(err, user) {
        if (err) {
            onComplete({
                success: false,
                err: err
            })
        }
        if (socialRegistry){
            onComplete(user)
        } else {
            onComplete({
                success: true,
                obj: user
            })
        }
    });
}

There are some answers that are great for posterity, this may not be one of them, but there is power in simplicity.


Oh, and to answer one of the questions you post in your post, the reason why 'result' never gets set to anything is that your function has already completed and has an implicit return after the async call to user.save().

John Green
  • 13,241
  • 3
  • 29
  • 51