tomalex
tomalex

Reputation: 1271

Chaining multiple request using bluebird

I'm trying to convert my existing code using BlueBird, please suggest a best option to chain multiple request. Error happening in each callback needs to be redirected to rendered with different error.

request(option1, function (error, response, body) {
    if (!error && response.statusCode == 200) {
       var data= JSON.parse(body);

       if(data.valid){

           if(data.expired){

               next();
           } else {

               request(option2, function (error2, response2, body2) {
                 var data2= JSON.parse(body2);
                 if(data2.valid) {
                    request(option3, function (error3, response3, body3) {
                        next();
                    })
                 } else {
                    res.json({error:'Error1'});
                 }
               })

          }
        } else {
           res.json({error:'Error2'});
        }
     } else {
        res.json({error:'Error3'});
     }
})

Upvotes: 2

Views: 176

Answers (2)

Mehran Hatami
Mehran Hatami

Reputation: 12961

var rp = require('request-promise');

function handleError(err) {
  res.json({
    error: err.message
  });
}

function parse(data) {
  if (data) {
    return JSON.parse(data);
  }
}

rp(option1)
  .then(parse)
  .then(function (data) {
    if (!data || !data.valid) {
      throw Error('Error2');
    }
    if (data.expired) {
      return;
    }
    return option2;
  })
  .then(rp)
  .then(parse)
  .then(function (data2) {
    if (!data2 || !data2.valid) {
      throw Error('Error1');
    }
    return option3;
  })
  .then(rp)
  .then(parse)
  .then(function () {
    next();
  })
  .catch(handleError);

You don't need to manually check for statusCode but if you need to do so, first you have to add resolveWithFullResponse attribute to your option1 object, which allows you to receive the response object:

function checkStatusCode(response) {
  if (response.statusCode !== 200) {
    throw Error('Error3');
  }
  return response.body;
}
// add resolveWithFullResponse attribute to option1
option1.resolveWithFullResponse = true;
rp(option1)
  .then(checkStatusCode)
  .then(parse)
  //...

Upvotes: 0

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276296

This is pretty straightforward, also note your current code doesn't handle errors in the second and third requests and this does:

var request = require("request-promise"); // request - converted to bluebird

request(option1).then(data=> {
  if(!data.valid) throw Error("Error3");
  if(data.expired) return;
  return request(option2).then(JSON.parse);
}).then(data2 => {
  if(!data2) return; // didn't need to fetch additional data
  if(!data2.valid) throw Error("Error2");
  return request(option3);
}).then(() => {
  next();
}, e => {
  res.json(error: e.message); 
  // better log this. 
});

Upvotes: 1

Related Questions