Search code examples
javascriptnode.jses6-promise

Promisifying my https.get() function is returning Promise { <pending> }


I'm trying to promisify a function that uses https.get() to get data from an API, so that I can use async await. Here is the example below, it retrieves the data however if I do anything to access the object, such as theData[0] shown below, it will only return Promise { <pending> }

Why am I not able to get asynchronous operation I'm trying for below? Or is there a better way to do this? Basically I'm just trying to make an asynchronous operation with async await, and I need to use https (not fetch, axios, etc).


const myRequest = ((url) => {
  return new Promise((resolve, reject) => {
    https.get(url, res => {
      let data = [];
      res.on('data', chunk => {
        data.push(chunk);
      });
      res.on('end', () => {
         resolve(JSON.parse(data));
      });
      }).on('error', err => {
        console.log('Error: ', err.message);
      });
  });
});


async function getApi() {
  // write your code here
  let url = [url redacted]

  await myRequest(url)
    .then(data => {
      console.log(data[0])
    })
    .catch(err => {
      console.log(err)
    });
}


Edit: refactored my helper function with the error handler:

 }).on('error', err => {
        reject(err)
      });

However the promise is still not delivering properly. If I do a simple console.log of the data

async function getApi() {
  let url = [url redacted]
  const data = await myRequest(url);
  console.log(data)
}

It will return Promise { <pending> } and then the JSON:

Promise { <pending> }
{
  page: 1,
  per_page: 500,
  total: 1,
  total_pages: 1,
  data: [
    {
      date: '5-January-2000',
      open: 5265.09,
      high: 5464.35,
      low: 5184.48,
      close: 5357
    }
  ]
}

I can access that object in the console.log, however, if i try to access anything in this object, it just returns Promise { <pending> }. Such as :

async function getApi() {
  let url = [url redacted];
  const data = await myRequest(url)
  const {high, open} = data.data[0];
  return `High: ${high} \n Open: ${open}`
}

Solution

  • First, you need to handle reject as well, or an error will cause a hang. Add reject(err) to your error handler to correctly bubble up the error.

    Once you're sure the issue isn't an error, the await usage needs work. await is a tool that takes a promise, and then waits until it resolves to execute synchronously. If you then an awaited promise, you're not getting anything out of your await.

    Rewrite the getApi function as:

    async function getApi() {
      let url = [url redacted]
      const data = await myRequest(url);
      console.log(data);
    }
    

    That will get and log the data, and if the promise is properly rejected, it will bubble that up as an exception.