0
votes

I have been struggling for quite some time to get this multiple async nodejs request apis to work but unfortunately i am not able to get them work.

Index.js Code:

service.get(
  "/restraunts",
  versionRoutes({
    "1.0.0": getRestrauntsList
  })
);

function getRestrauntsList(req, res, next) {
  console.log("Started getRestrauntsList");
  file1
    .appEnvironment(req, res, next)
    .then(function(result) {
      return file2.getRestrauntsList(req, res, next);
    })
    .then(function(result) {
      res.status(200).send(result);
      return;
    })
    .catch(function(errorResult) {
      res.status(500).send(errorResult);
      return;
    });
}

File2.js

module.exports = {
  getRestrauntsList: function(req, res, next) {
    console.log("getRestrauntsList started..");
    var cities = [1, 2, 3, 4, 5];
    let restrauntsList = [];
    let urlArray = [];
    var restrauntsListPromise = cities.map(function(id) {
      return new Promise(function(resolve, reject) {
        var options = {
          method: "GET",
          url: "someurl/" + id + "/restaurants",
          headers: {
            "AUTH-TOKEN": "TOKEN"
          }
        };
        request(options, function(error, response, body) {
          if (error) {
            if ("message" in error) {
              errorMsg = error.message;
              var result = {
                status: "error",
                message: errorMsg
              };
            } else {
              var result = {
                status: "error",
                message: "Resource Timeout."
              };
            }
            reject(result);
            return promise;
          }
          console.log(
            "Response: " + JSON.stringify(response)
          );
          if (response.statusCode === 200 || response.statusCode === 201) {
            body = JSON.parse(body);
            if (body.success) {
              let result = {
                status: "success",
                data: body.result
              };
              resolve(result);
            } else {
              let result = {
                status: "error",
                message: body.error
              };
              reject(result);
            }
          } else {
            let result = {
              status: "error",
              message: body.error
            };
            reject(result);
          }
        });
      });
    });
    console.log('restrauntsListPromise:' + JSON.stringify(restrauntsListPromise));
    Promise.all(restrauntsListPromise).then(function(result) {
      var content = result.map(function(restraunts) {
        return restrauntsList.push(restraunts.body);
      });
      //  res.send(content);
      resolve({
        restrauntsList: restrauntsList
      });
      return promise;
    });
  },
};

Ideally i expect to get the response of all the apis in the

restrauntsListPromise

and then using Promise.all i should iterate all the promises and formulate my required object.

The response of my code however is

restrauntsListPromise:[{},{},{},{},{}]

and then

Response: {"statusCode":200,"body":"{\"success\":true,\"res

Response: {"statusCode":200,"body":"{\"success\":true,\"res

Response: {"statusCode":200,"body":"{\"success\":true,\"res

Response: {"statusCode":200,"body":"{\"success\":true,\"res

Response: {"statusCode":200,"body":"{\"success\":true,\"res

Ideally what should happen is i should be able to pass the combined result of all the five apis calls as a single object back to the calling promise here

.then(function(result) {
    res.status(200).send(result);
    return;
  })

The problem being the method getRestrauntsList finishes execution and then after some time, i get the responses of the apis.

2
What is your question?Code-Apprentice
return restrauntsList.push(restraunts.body); is wrong. You are returning the return value of push(). Is that what you want?marekful
i would want to return the results of all the 5 apis calls as a single object and access that in .then(function(result) { res.status(200).send(result); return; })Doe
The code is hard to understand because of poor indentation. You could use request-promise for starters to get rid of that nested functions.Estus Flask
"i should be able to pass the combined result " — If you want to combine them, then you need to write code to do that (in whatever way you want them combined).Quentin

2 Answers

1
votes

The problem being the method getRestrauntsList finishes execution and then after some time, i get the responses of the apis.

This is because you're not returning a promise from the getRestrauntsList().

There are few items that needs to addressed to make it work

1. Remove the unused variables

return promise; // both inside promise.all[] and request()

There is no declared variable named promise. So, you can remove it.

2. Accessing .body instead of .data

You're resolving as resolve({status: "success", data: body.result}); But When you are iterating, you are accessing using .body instead of .data. You need to be using .data. Also, you can eliminate restrauntsList array since you're using a .map()

3. Calling resolve() to return values.

You can't use resolve() to return value within Promise.all[] since you didn't create a promise using new Promise((resolve, reject) => { ... });. By default, a return within a promise will be a promise. so, a simple return will suffice. But if you want to be explicit, you can also return using Promise.resolve()

Making those changes,

return Promise.all(restrauntsListPromise).then(function (result) {
  return {
    restrauntsList: result.map(function (restraunts) {
      return restraunts.data;
    })
  };

  //or using Promise.resolve();
  // return Promise.resolve({
  //   restrauntsList: result.map(function (restraunts) {
  //     return restraunts.data;
  //   })
  // });
});
0
votes

You are looking for

return Promise.all(restrauntsListPromise).then(function(result) { /*
^^^^^^ */
    var contents = result.map(function(restaurants) {
        return restaurants.body;
//      ^^^^^^^^^^^^^^^^^^^^^^^^
    });
    return {restaurantsList: contents};
//  ^^^^^^
});

You need to return the promise chain from the getRestrauntsList method, you should return the value from the map callback instead of using push on an array, and you will need to return from the then callback - there is no resolve function as you're not inside a new Promise constructor that you only need for callback APIs.