Dev Matee
Dev Matee

Reputation: 5939

How to keep Waiting the nested function to return value to parent function

Below is the piece of code. I'm always getting initial value of valid variable as the last return statements run before the DB Query completely executes.

async login(username, password, ctx) {
        let sql = 'SELECT * FROM users WHERE username=?;'

        let valid = false; //I'm always getting this value

        await this.db.query(sql, [username], function(err, rows, fields){
            console.log(rows);
            if(rows.length > 0)
            {
                console.log('coming into');
                console.log(JSON.stringify(rows));
                valid = bcrypt.compare(password, rows[0].pass)
                console.log('valid is ', valid);    
                if(valid === false) throw new Error(`invalid password for account "${username}"`)
                ctx.session.user_id = rows[0].id
                ctx.session.authorised = true
                return ctx.redirect(`/secure?msg=you are now logged in...`)
            }
            else
                throw new Error(`username ${username} not found ${JSON.stringify(rows)}`);

            return valid;
        });

    }

Upvotes: 1

Views: 115

Answers (1)

eol
eol

Reputation: 24565

One way to fix this is to wrap the db-call in a promise and wait for this promise to resolve/reject. Then, you can either set the authorised-flag and redirect the user or handle the error:

async login(username, password, ctx) {

    try {
        const rows = await new Promise((resolve, reject) => {
            let sql = 'SELECT * FROM users WHERE username=?;'
                this.db.query(sql, [username], function (err, rows, fields) {
                    if (rows && rows.length > 0) {
                        console.log('coming into');
                        console.log(JSON.stringify(rows));
                        valid = bcrypt.compare(password, rows[0].pass)
                        console.log('valid is ', valid);
                        if (valid === false) {
                            reject(new Error(`invalid password for account "${username}"`));
                        }
                        return resolve(rows);
                    }
                    reject(new Error(`username ${username} not found ${JSON.stringify(rows)}`); )
                });

        });
        ctx.session.user_id = rows[0].id
        ctx.session.authorised = true
        return ctx.redirect(`/secure?msg=you are now logged in...`)
    } catch (err) {
        // handle your error, e.g. ctx.redirect('/error-page')
    }

}

Upvotes: 1

Related Questions