0

I am trying to create a function that returns the data from a Node http request, so that the data can be stored in a variable to be used afterwards. The function places the data in an array, and the array is returned from the function. Then, I invoke the function and assign the result to a variable.

I am able to successfully get the data with the http request and place the date in the array, but there are two problems with the current implementation.

  1. When I try to access the variable containing the function results, the result is Promise { <pending> }. I understand this is because the async function hasn't completed doing its work, but I'm not sure how set up the code so that it waits to use the variable until after the promise is done. The function is an async function, and it is awaiting the http request, so I thought it would wait for the function to complete its work before moving down to the next line of code (such as the console of the variable).

  2. When I use setTimeout to look at the variable after some time has passed, the variable does contain what the function returned, so it does receive the data eventually, but the data in the variable is still inside a promise, so I am unable to retrieve the items from it.

This is my code:

require('dotenv').config();
const https = require('https');
const potionsUrl = process.env.POTIONS_URL;

const getData = async (url) => {
  const list = [];
  await https
    .get(url, (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        const parsedData = JSON.parse(data);
        list.push(...parsedData);
      });
    })
    .on('error', (error) => {
      console.log(error);
    });

  return list;
};

const potions = getData(potionsUrl);

console.log(potions);

// Do other stuff with potions

This is what displays in the console:

IMMEDIATE POTIONS
Promise { <pending> }
POTIONS AFTER 5 seconds:
Promise {
  [
    {
      id: 11,
      potion: 'Truthy Yes Serum',
      spell_level: 2,
      tasty: false,
      brand: 'Arkex Brews'
    },
    {
      id: 14,
      potion: 'Langstons Majical Beans',
      spell_level: 13,
      tasty: false,
      brand: 'Arkex Brews'
    }
  ]
}

Franco Ortega
  • 29
  • 1
  • 6
  • You should check what is being saved in the data variable when doing the reassignment with addition. You will have a better perspective on what information is being acquired. Then you should check the content once formatted to JSON, to finally know what you are saving in that array. – Diesan Romero Jul 08 '22 at 01:45
  • `https.get()` does not return a promise. Therefore you cannot `await` it. – slebetman Jul 08 '22 at 01:59
  • It looks like the chunk is an object, and adding the chunk to the data string results in data being a string that contains the data from the chunk in string form. So essentially, the addition turns the chunk into a string. The content being spread into the array is an array. – Franco Ortega Jul 08 '22 at 18:35

1 Answers1

0

You should first understand what a promise is, I don't think you understand what a promise is. await is no working, because https.get is no return a promise. You need to create a promise first.

// a new promise 
const get = url => new Promise((reslove, reject) => {
   https.get(url, res => {
     let data = '';

     res.on('data', (chunk) => {
       data += chunk;
     });

     res.on('end', () => {
       reslove(JSON.parse(data));
     });

     res.on('error', error => {
       reject(error);
     });
   });
});
// use it
require('dotenv').config();
const https = require('https');
const potionsUrl = process.env.POTIONS_URL;
get(potionsUrl).then(potions => {
  console.log(potions );
});
jaran-Www
  • 41
  • 1
  • Thank you. This was helpful. I tried using the `.then` syntax earlier, but it came up empty. It looks like the solution was to wrap the http request inside a new Promise. Also, it sounds like a function that makes an http request can never return the result of that request, correct? The result of the request can only be used inside the `.then` chain. I feel confused by this because I believe when I make client-side requests, I can save the result to a variable that can be used later in the code, such as `const result = fetch(URL)`. Not sure why it works differently for server-side requests. – Franco Ortega Jul 08 '22 at 19:18