Javascript Promise: Resolve not Waiting

I have read other related posts and still am not understanding correctly how to use promises.

router.get('/', ensureAuthenticated, function(req, res) {
    let promiseToGetResponses = new Promise(function(resolve, reject) {
        var indexData = new getIndexData();
        resolve(indexData);
        console.log('received ' + indexData.length);
    });

    promiseToGetResponses.then(function(data) {
        console.log('then data length ' + data.length);
        res.render('index', {rsvpsIn: data});
    }).catch(function() { });
});

Console shows this:

received undefined
then data length undefined
returned 1 *** this is from a console.log inside the getIndexData().

The function is getting the data, but my promise usage is not waiting for it.

Thanks.

P.S. I didn't know the getIndexData function was needed. Here it is:

function getIndexData(){
    RSVP.find({response: 'in'}, function (err, data) {
        if (err) throw err;

        // This will be a list of all responses to show in the view
        var rsvpsIn = [];

        if (data.length > 0) {
            // Use because the foreach loop below has async calls.
            var responseCounter = data.length;
            data.forEach(function(response) {
                var foundUser = User.getUserById(response.userId, function(err, user) {
                    var newRSVP = {userName: user.username, notes: response.notes};
                    rsvpsIn.push(newRSVP);

                    // decrement and if we are done, return list
                    responseCounter -= 1;

                    if (responseCounter == 0) {
                        console.log('returned ' + rsvpsIn.length);
                        return rsvpsIn;
                    }
                });
            });
        } else {
            return rsvpsIn;
        }
    });
}

1 answer

  • answered 2017-11-12 19:54 bryan60

    Not familiar with RSVP but it appears to be callback based API, so you should wrap it in a promise and just use the promise directly:

    function getIndexData(){
        return new Promise((resolve, reject) => {
            RSVP.find({response: 'in'}, function (err, data) {
                if (err) reject(err);
    
                // This will be a list of all responses to show in the view
                var rsvpsIn = [];
    
                if (data.length > 0) {
                    // Use because the foreach loop below has async calls.
                    var responseCounter = data.length;
                    data.forEach(function(response) {
                        var foundUser = User.getUserById(response.userId, function(err, user) {
                            var newRSVP = {userName: user.username, notes: response.notes};
                            rsvpsIn.push(newRSVP);
    
                           // decrement and if we are done, return list
                            responseCounter -= 1;
    
                            if (responseCounter == 0) {
                                console.log('returned ' + rsvpsIn.length);
                                resolve(rsvpsIn);
                            }
                        });
                    });
                } else {
                    resolve(rsvpsIn);
                }
            });
        });
    }
    

    then just use it where you use the promise:

    router.get('/', ensureAuthenticated, function(req, res) {
        getIndexData().then(function(data) {
            console.log('then data length ' + data.length);
            res.render('index', {rsvpsIn: data});
        }).catch(function() { });
    });