DEV Community

Discussion on: Handling async await

Collapse
 
jaakofalltrade profile image
Jaako

I think you can just async await the callback.


_verifyEmail(User).then(async res => {
        emailStatus = await res;
        console.log(`res: ${res}`);
});

Collapse
 
itssimondev profile image
Simone Aronica • Edited

I think you are the most intelligent person in the world.
I'll try this right away! Thanks!

Edit: unfortunately same result, it's still not working for some reason...

Collapse
 
jaakofalltrade profile image
Jaako

I think I have found the problem, you're console logging res instead of emailStatus.

Thread Thread
 
itssimondev profile image
Simone Aronica • Edited

I'm console logging both, but that's not the problem. The problem is that when _verifyEmail ends the result is a promise instead of an actual value.

Edit:
When I execute this code:

function _createUser(userinfo){
    var User = new UserModel(userinfo);
    var status;
    status = _saveUser(User);
    console.log(`_saveUser returned ${status}`);
    if(status === 203)
        return 201;
    return 400;
} 

function _verifyName(User){
    const { name } = User;
    if(!name.match(/[A-Za-z]/g))
        return 400;
    return 202;
}

function _verifySurname(User){
    const { surname } = User;
    if(!surname.match(/[A-Za-z]/g))
        return 400;
    return 202;
}

async function _verifyEmail(User){
    const { email } = User;
    /* const { wellFormed, validDomain, validMailbox } = await validator.verify(email); */
    var isAvailable = await UserModel.countDocuments({email}).
        then(res => {
            isAvailable = res > 0 ? false : true;
            var isValid = EmailValidator.validate(email)
            /* console.log(`wellFormed: ${wellFormed}`);
            console.log(`validDomain: ${validDomain}`);
            console.log(`validMailbox: ${validMailbox}`); */
            console.log(`isValid: ${isValid}`)
            console.log(`isAvailable: ${isAvailable}`);
            if(!!isValid || !isAvailable)
                return 400;
            else
                return 202;  
        });
    return isAvailable;
}

function _verifyPassword(User){
    const { password } = User;
    if(password.lenght < 8 || password.lenght > 24 || !password.match(/[A-Za-z0-9!-/]/g))
        return 400;
    return 202;
}

function _verifyUser(User){
    var emailStatus;
    _verifyEmail(User).then(async res => {
        emailStatus = await res;
        console.log(`res: ${res}`);
    });

    const passwordStatus = _verifyPassword(User);
    const nameStatus = _verifyName(User);
    const surnameStatus = _verifySurname(User);

    console.log(`email status: ${emailStatus}`);
    console.log(`password status: ${passwordStatus}`);
    console.log(`name status: ${nameStatus}`);
    console.log(`surname status: ${surnameStatus}`);

    if(emailStatus === 400 || passwordStatus === 400 || nameStatus === 400 || surnameStatus === 400)
        return 400;
    else
        return 202;
}

function _saveUser(User){
    var status = _verifyUser(User);
    console.log(`_verifyUser returned ${status}`);
    if(status === 400)
        return 400;
    else
    {
        User.save().then(status = 201);
        return status;
    }
}

I get this as a result:

email status: undefined
password status: 202
name status: 202
surname status: 202
_verifyUser returned 202
_saveUser returned 201
isValid: true
isAvailable: false
res: 400

but _verifyUser should be a 400 (look at res) since there is already a user with the mail I've sent.

Thread Thread
 
jaakofalltrade profile image
Jaako • Edited

Ok, the problem is you cannot pass a value to emailStatus coming from the .then method:

I have encountered this problem before but I forgot how I got to the bottom of it.
This post should help.

var emailStatus; // You cannot pass a value here
_verifyEmail(User).then(async res => {
        // Coming from here, the value inside this scope is only contained 
        // inside this scope correct me if I'm wrong.
        emailStatus = await res;
        console.log(`res: ${res}`);
    });

I think there are two ways to solve this problem,

The first one requires you to add an async in _verifyUser:


async function _verifyUser(User){
    var emailStatus = await _verifyEmail(User); // Here
    const passwordStatus = _verifyPassword(User);
    const nameStatus = _verifyName(User);
    const surnameStatus = _verifySurname(User);

    console.log(`email status: ${emailStatus}`);
    console.log(`password status: ${passwordStatus}`);
    console.log(`name status: ${nameStatus}`);
    console.log(`surname status: ${surnameStatus}`);

    if(emailStatus === 400 || passwordStatus === 400 || nameStatus === 400 || surnameStatus === 400)
        return 400;
    else
        return 202;
}

The second one is a little bit experimental because i don't know if it will work:
Edit: Come to think of it this will not work, it will only return a promise I think.

function _verifyUser(User){
    // here
    var emailStatus = _verifyEmail(User).then(async res => {
        return emailStatus = await res;
    });
    const passwordStatus = _verifyPassword(User);
    const nameStatus = _verifyName(User);
    const surnameStatus = _verifySurname(User);

    console.log(`email status: ${emailStatus}`);
    console.log(`password status: ${passwordStatus}`);
    console.log(`name status: ${nameStatus}`);
    console.log(`surname status: ${surnameStatus}`);

    if(emailStatus === 400 || passwordStatus === 400 || nameStatus === 400 || surnameStatus === 400)
        return 400;
    else
        return 202;
}