Using Q promises in HTTP requests with NodeJs

I am trying to chaining promises functions that use HTTP requests in NodeJS with Kraken framework.

My code could work 90% of the time, but if the remote server asks for a time to respond, the code will return an error with undefined values. Therefore, I think Q is a good solution to prevent this.

Here's the situation:

We access the URL with the "code" parameter -> the route controller takes this parameter to use it in the HTTP POST request -> the response (token) is stored in a variable and used in another HTTP GET request -> the response (multiple JSON objects) is also stored in a variable → all variables are stored in MongoDB. If functions are not used in that order, of course it fails.

var Q = require('q');

module.exports = function (router) {
  router.get('/', function (req, res) {
    var codein = req.param('code');
    if(codein){
        console.log('Provided code: ' + codein+'\n');
        getAccessToken(codein).then(function(token){
            console.log('Provided AccessToken: ' + token + '\n');
            getUsername(token).then(function(userdata){
                console.log('Provided Username: ' + JSON.parse(userdata).username + '\n');
                storeData(userdata).then(function(msg){
                    console.log(msg);
                    res.redirect('/dashboard/' + JSON.parse(userdata).username);
                });
            });
        });

    }
    else{
        console.log('Access Denied, redirecting...');
        res.redirect('/');
    }
  });
};

      

This method works, but didn't actually solve the problem because sometimes the variables are undefined again. I think these are my request functions which are not well done ...

Here's an example of the first function with a POST request:

var getAccessToken = function(cod){
    var def = Q.defer();
    var data = querystring.stringify({
            client_id:"1234567890", 
            client_secret:"******", 
            grant_type:"authorization_code", 
            redirect_uri:"http://localhost:8000/r/callback", 
            code:cod
    });

    var options = {
        host: 'domain.server.com',
        port: 443,
        path: '/api/oauth2/token',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(data)
        }
    };

    var response = "";

    var req = https.request(options, function(res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            response += chunk;
        });

        res.on('end', function(){
            var json = JSON.parse(response);
            var acto = json.access_token;
            def.resolve(acto);

        });
    });

    req.write(data);
    req.end();
    return def.promise;

};

      

In this case, the acto variable might be undefined ... Am I using Q incorrectly?

EDIT

To understand my problem, let me show you what I have in my output console (really rare, but it happens):

Provided code: 12345678910

Provided Username: user543210

      

Instead:

Provided code: 12345678910

Provided AccessToken: 9876543210

Provided Username: user

      

+3


source to share


1 answer


I think you need to consider 2 scenarios

  • If the Twitch API takes time to respond.
  • Twitch response could not be parsed

Code



    res.on('end', function(){
        var json = JSON.parse(response);
        var acto = json.access_token;
        def.resolve(acto);
    });

      

Should be changed as:

    try {    
       var json = JSON.parse(response);
       var acto = json.access_token;
       //check if acto is undefined
       if (acto === undefined) {
         def.reject('Some error message');
       } else {
         def.resolve(acto);
       }
    } catch (error) {
      //since the JSON could not be parse
      def.reject(error);
    }

      

+2


source







All Articles