Home > Back-end >  What would be a proper way of returning this promise?
What would be a proper way of returning this promise?

Time:02-05

I'm new to coding and Promises are somewhat of an abstract concept for me. I know that in order to return a Promise you must use .then and .catch , but I'm unsure how exactly they should be used in the following code.

/**
 * Make an HTTPS request to the MTA GTFS API for a given feed.
 * @param  {String} baseUrl    - base URL for MTA GTFS API
 * @param  {String} feedId     - identifier for which realtime feed
 * @param  {String} apiKey     - key for MTA GTFS API
 * @return {<Object>}          - Promise of parsed feed.
 */

function makeRequest(baseUrl, feedId, apiKey) {
  const feedUrl = baseUrl   feedId;
  
  return new Promise((resolve, reject) => {
    const req = https.request(feedUrl,
      { headers: { 'x-api-key': apiKey } },
      (res) => {
        if (res.statusCode < 200 || res.statusCode >= 300) {
          return reject(new Error('statusCode='   res.statusCode));
        }
        var data;
        data = [];
        res.on('data', (chunk) => {
          return data.push(chunk);
        });
        return res.on('end', function() {
          var msg;
          data = Buffer.concat(data);
          try {
            msg = nstrDecoder.decode(data);
          } catch (err) {
            try {
              console.log(err.message);
              msg = nsssDecoder.decode(data);
            } catch (err) {
              console.log(err.message);
              msg = "";
            }
          }
          resolve(msg);
        });
      }
    );
    req.on('error', (e) => {
      reject(e.message);
    });
    req.end();
  });

}

return console.log(makeRequest(baseUrl, feedId, apiKey));

After running this code I get a message saying the Promise is pending. Thoughts??

CodePudding user response:

When calling a function that returns a promise, you're going to get the promise in a pending state being it hasn't resolve or rejected yet. You have two options.

Option one. node 10 you can use async await.

async function main(){
const res = await makeRequest(baseUrl, feedId, apiKey)
return res
}

Pre node 10

makeRequest(baseUrl, feedId, apiKey)
  .then(data => {
    console.log(data)
  })
  .catch(err => {
    console.log(err)
  })

Essentially if you have to wait for the data, you have to have the code that relies on that data after the await, or in the .then block.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

CodePudding user response:

Your makeRequest() function returns a promise. To use that promise, you use .then() or await to get the resolved value from the promise.

Using .then():

makeRequest(baseUrl, feedId, apiKey).then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

or using await:

async function someFunction() {
    try {
        let result = await makeRequest(baseUrl, feedId, apiKey);
        console.log(result);
    } catch(e) {
        console.log(err);
    }
}

FYI, a lot of what makeRequest() is doing can be done simpler using an http request library that already supports promises. There is a list of competent libraries to choose from here.

My favorite is got(), but you can review the list to decide which one you like. The main advantages are that they already collect the whole response for you, already support promises, support a wide variety of authentication schemes with built-in logic and can often decode or parse the response for you - all things which https.request() does not know how to do by itself.

  •  Tags:  
  • Related