Alex
Alex

Reputation: 433

Node.js wait until request is done

I'm trying to make a simple app that requests some data from an API. I'm building it with express and I have the following code that does the request:

module.exports = {
    getPrevMatches: function(){
        request({
            uri: 'http://worldcup.sfg.io/matches',
            json: true
        }, this.process);
    },
    process: function(error, response, body){
        if(response.statusCode === 200){
            return body;
        }
    }
}

And the following in my express script:

app.get('/previous', function (req, res){
    var prevMatches = worldcup.getPrevMatches();

    console.log(prevMatches);

    res.render('prev.html', {
        prevMatches: prevMatches
    });
});

prevMatches is always undefined at this point. I thought that the request package would wait until, well, the request was finished and then proceed with my code. Is this not the case?

Thanks.

Upvotes: 0

Views: 11329

Answers (2)

Dmitriy Nevzorov
Dmitriy Nevzorov

Reputation: 6078

It is a good use case for promises. There are many libs, you can use https://www.npmjs.com/package/request-promise for example.

var rp = require('request-promise');
module.exports = {
    getPrevMatches: function(){
        return rp({
            uri: 'http://worldcup.sfg.io/matches',
            json: true
        });
    }
}

I'm not sure if this.process would work in this context

app.get('/previous', function (req, res){
    var prevMatches = worldcup.getPrevMatches();
    prevMatches.then(function (data) {
      console.log(data);

      res.render('prev.html', {
          prevMatches: data
      });
    })
    prevMatches.catch(function (e) {
      res.status(500, {
          error: e
      });
    });
});

Upvotes: 1

Maurits Rijk
Maurits Rijk

Reputation: 9985

Using a callback based approach (like stated in the comments):

function getPrevMatches(cb) {
    request({
        uri: 'http://worldcup.sfg.io/matches',
        json: true
    }, function(error, response, body){
        if (response.statusCode === 200){
            cb(body);
        }
        // Do error handling here!
    });
}

module.exports = {
    getPrevMatches: getPrevMatches
}

As you can see there is no need to export the process function. The calling code now becomes:

app.get('/previous', function(req, res){
    worldcup.getPrevMatches(function(prevMatches) {
        console.log(prevMatches);

        res.render('prev.html', {
            prevMatches: prevMatches
        });
    });
});

First remark: you still have to handle the errors from the request call (added as a comment).

Second remark: you might want to like at a Promises based approach to avoid callback hell. Request has a very nice promises based wrapper called conveniently request-promise

Upvotes: 2

Related Questions