Search code examples
javascriptnode.jsrequestpromisebluebird

how do I use promise for a single variable?


I need to do two http requests. The second http request requires information from the first one. The first request is to set the variable 'amount' which is used during the second request.

This is a codesection of mine.

(the variables 'url' and 'number' are existent, foo() is something else.)

var Promise = require('bluebird');
var request = require('request-promise');
var amount;


request({url: url, json: true }, function(error, response, body) {
          if (!error && response.statusCode == 200) {
            amount = body.num;
          }
        }).then(function(data) {
          if (number == null || number > amount) {
            number = Math.floor(Math.random() * amount) + 1;
          }

          request({
            url: url,
            json: true
          }, function(error, response, body) {
            if(!error & response.statusCode == 200) {
              foo();
            }
          });  
        });

the code is working but it is not beautiful with this nesting of requests. Is there a way to make a promise of a variable and then trigger a function when that variable has been set ?


Solution

  • You're using request-promise but still using old-fashioned callbacks, which is why things look so cluttered.

    It's hard to make out what you're trying to do, but if the second request relies on information from the first, you put it in a then callback and return the new promise it gives you:

    var Promise = require('bluebird');
    // I changed `request` to `rp` because `request-promise` is not `request`, that's one of its underlying libs
    var rp = require('request-promise');
    
    // Do the first request
    rp({ url: url, json: true })
        .then(function(data) {
            // First request is done, use its data
            var amount = data.num;
            // You didn't show where `number` comes from, assuming you have it in scope somewhere...
            if (number == null || number > amount) {
                number = Math.floor(Math.random() * amount) + 1;
            }
            // Do the next request; you said it uses data from the first, but didn't show that
            return rp({ url: url, json: true });
        })
        .then(function() { // Or just `.then(foo);`, depending on your needs and what `foo` does
            // Second request is done, use its data or whatever
            foo();
        })
        .catch(function(error) {
            // An error occurred in one of the requests
        });