Return value 'undefined' because of asynchronism

1

I have a file named validationForgetPassword.js with the following code:

"use strict"

var config = require('./config'),
    createHash = require('sha.js'),
    pgPromise = require('./pgPromise'),
    winston = require('./winston');

module.exports = function (id, time, hashForgetPassword) {
    var date = new Date();
    date = date.getTime();

    if (date > time) {
        logger.log('error', 'date expirated');
        return null;
    }

     pgPromise.db.oneOrNone('select dr_email, dr_tax_id, dr_license, dr_first_name, dr_last_name, dr_cell_phone from driver where dr_id = ($1)', [id])
    .then(function (results) {
        if (results) {
            results.time = time;
            var result = JSON.stringify(results);

            var sha256 = createHash('sha256')
            var hash = sha256.update(result, 'utf8').digest('hex');

            console.log(hash);
            console.log(hashForgetPassword);

            if(hashForgetPassword === hash) {
                return 1;
            } else {
                logger.log('error', 'hash is not valid');
                return null;
            }
        } else {
            logger.log('error', 'Not result in select driver');
            return null;
        }
    }).catch(function (error) {
        logger.log('error', 'Error in select driver from module validationForgetPassword \n' + error);
        return null;
    });
}

And a server.js with the following code:

var express = require('express'),
    bodyParser = require('body-parser'),
    cors = require('cors');
    path = require ('path');

var login = require('./api/routes/login'),
    logoff = require('./api/routes/logoff'),
    forgetPasswordUser = require('./api/routes/forgetPasswordUser');
    importEvents = require('./api/routes/importEvents'),
    taskWorker = require('./api/routes/taskWorker'),
    create = require('./api/routes/create'),
    validationForgetPassword = require('./config/validationForgetPassword');
    winston = require('./config/winston');

var app = express();

app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.set('views', __dirname + '/api/views');

new winston();
importEvents();
taskWorker();

var port = process.env.PORT || 8080;

app.use('/api/v1/driver/login', login);
app.use('/api/v1/driver/logoff', logoff);
app.use('/api/v1/driver/create', create);
app.use('/forgetPasswordUser', forgetPasswordUser);

app.get('/forgetPassword/:id/:time/:hash', function(req, res) {

    const id = req.params.id;
    const time = req.params.time;
    const hash = req.params.hash;

    var token;
    token = validationForgetPassword(id, time, hash);

    if (token == 1) { 
        res.render('pages/forgetPassword');
    } else {
    //res.render('pages/forgetPassword/oi');
    }
});

app.listen(port);
console.log('API started on port ' + port);

However, the result returns undefined, because it executes if before the return.

    
asked by anonymous 11.08.2016 / 21:43

1 answer

2

The problem is asynchronous. There are several questions here that mention this in Ajax for example. In this case with Promises is basically the same.

So in your module you can use callbacks old fashion or a Promise. Here's an example with Promise. See part return new Promise((resolve, reject) => {

"use strict"

var config = require('./config'),
    createHash = require('sha.js'),
    pgPromise = require('./pgPromise'),
    winston = require('./winston');

module.exports = function(id, time, hashForgetPassword) {
    var date = new Date();
    date = date.getTime();

    if (date > time) {
        logger.log('error', 'date expirated');
        return null;
    }
    return new Promise((resolve, reject) => {
        pgPromise.db.oneOrNone('select dr_email, dr_tax_id, dr_license, dr_first_name, dr_last_name, dr_cell_phone from driver where dr_id = ($1)', [id])
            .then(function(results) {
                if (results) {
                    results.time = time;
                    var result = JSON.stringify(results);

                    var sha256 = createHash('sha256')
                    var hash = sha256.update(result, 'utf8').digest('hex');

                    console.log(hash);
                    console.log(hashForgetPassword);

                    if (hashForgetPassword === hash) return resolve(1);
                    logger.log('error', 'hash is not valid');
                    reject('hash is not valid');
                } else {
                    logger.log('error', 'Not result in select driver');
                    reject('Not result in select driver');
                }
            }).catch(function(error) {
                logger.log('error', 'Error in select driver from module validationForgetPassword \n' + error);
            });
    });

}

and in the file that requires this module you can do:

var validationForgetPassword = require('./config/validationForgetPassword');
// ...

app.get('/forgetPassword/:id/:time/:hash', function(req, res) {

    const id = req.params.id;
    const time = req.params.time;
    const hash = req.params.hash;

    validationForgetPassword(id, time, hash).then(token => {
        if (token == 1) res.render('pages/forgetPassword');
        else res.render('pages/forgetPassword/oi');
    }).catch(reason => {
        console.log(reason);
        res.redirect('/')
    });
});

In this way validationForgetPassword becomes a promise when invoked and you can use then that will receive as argument what you pass to resolve .

    
11.08.2016 / 22:23