user984003
user984003

Reputation: 29567

Wait for response from node.js request using await

Yes, I have seen many other questions and answers. I know I need to use a callback response. However, I still don't get how to do this particular example. Most examples involve a callback response that logs something or the post has hundreds of different answers.

How do I return the request response from getPageData?

var url = "myurl";
var name = await getPageData(url);
// wait until I get name and then do stuff with name

function getPageData(url)
{
    const https = require('https');
    https.get(url, (resp) => {
    
        let data = '';

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

        resp.on('end', () => {
            var name = JSON.parse(data);
            // what do I do here to get name out?
        });

    }).on("error", (err) => {
       console.log("Error: " + err.message);
    });
}

Upvotes: 0

Views: 1565

Answers (2)

jfriend00
jfriend00

Reputation: 707486

The higher level solution here is to use a module for making http requests that already supported promises. You can see a list of many of them here. My favorite from that list is got() and you can use it to solve your problem like this:

function getPageData(url) {
    return got(url);
}

// can only use await inside a function declared as async
async function someFunction() {
    try {
        let name = await getPageData(url);
        console.log(name);
    } catch(e) {
        console.log(e);
    }
}

The got() library does a whole bunch of things for you.

  1. It is entirely based on promises so you can directly use await on the promise it returns.
  2. It collects the whole response for you (you don't have to write your own code to do that).
  3. If the response is JSON, it automatically parses that for you and resolves to the parsed Javascript object.
  4. It automatically detects http or https URL and uses the right low level module.
  5. And, it has dozens of other useful features (not needed in this example).

Or, if you want the lower level solution where you make your own promisified function for doing an https request, you can do this:

const https = require('https');

// can only use await inside a function declared as async
async function someFunction() {
    const url = "myurl";
    try {
        let name = await getPageData(url);
        console.log(name);
    } catch(e) {
        console.log(e);
    }
}



function getPageData(url) {
    return new Promise((resolve, reject) => {
        https.get(url, (resp) => {

            let data = '';

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

            resp.on('end', () => {
                try {
                    const name = JSON.parse(data);
                    resolve(name);
                } catch(e) {
                    // JSON parsing error
                    reject(e);
                }
            });

        }).on("error", (err) => {
            console.log("Error: " + err.message);
            reject(err);
        });
    }).on('error', (err) => {
        console.log("Error: " + err.message);
        reject(err);
    });
}

Upvotes: 0

Christian
Christian

Reputation: 7852

await can only be used in async functions. You can however return a promise from getPageData and "await" using chained then:

Use the Promise object:

const https = require('https');

var url = "myurl";
var name; 
getPageData(url)
 .then(data => { name = data; /*This is the scope in which you would use name*/ })
 .catch(err => { console.log('Error occured', err); });

async function getPageData(url) {
  return new Promise((resolve, reject) => {
    https
      .get(url, resp => {
        let data = '';

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

        resp.on('end', () => {
          const name = JSON.parse(data);
          // what do I do here to get name out?
          resolve(name);
        });
      })
      .on('error', err => {
        console.log(`Error: ${err.message}`);
        reject(err);
      });
  });
}

Upvotes: 3

Related Questions