51

I am finding way out to use async / await with https post. Please help me out. I have posted my https post code snippet below.how do I use async await with this.

const https = require('https')

const data = JSON.stringify({
  todo: 'Buy the milk'
})

const options = {
  hostname: 'flaviocopes.com',
  port: 443,
  path: '/todos',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
}

const req = https.request(options, (res) => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', (d) => {
    process.stdout.write(d)
  })
})

req.on('error', (error) => {
  console.error(error)
})

req.write(data)
req.end()
Dhiraj Bastwade
  • 643
  • 1
  • 6
  • 12

3 Answers3

79

Basically, you can write a function which will return a Promise and then you can use async/await with that function. Please see below:

const https = require('https')

const data = JSON.stringify({
  todo: 'Buy the milk'
});

const options = {
  hostname: 'flaviocopes.com',
  port: 443,
  path: '/todos',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length
  },
};

async function doSomethingUseful() {
  // return the response
  return await doRequest(options, data);
}


/**
 * Do a request with options provided.
 *
 * @param {Object} options
 * @param {Object} data
 * @return {Promise} a promise of request
 */
function doRequest(options, data) {
  return new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      res.setEncoding('utf8');
      let responseBody = '';

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

      res.on('end', () => {
        resolve(JSON.parse(responseBody));
      });
    });

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

    req.write(data)
    req.end();
  });
}
Rishikesh Darandale
  • 3,222
  • 4
  • 17
  • 35
  • 1
    I was wondering, if you declare the `doRequest` function to be `async`, wouldn't it be equal to enclosing the code inside a promise? – Mooncrater Jul 11 '21 at 13:02
  • I have a question for `req.write(data)`. Doesn't it cause **write after end** error? What does it do here? (I am not really familiar with NodeJS, I though `write` is used to write file/print to consle) – SiegeSailor Sep 23 '22 at 15:01
  • @Mooncrater Interesting, but how would you define where to resolve and where to reject? Can you point to an example? Cheers. – noontz Jan 20 '23 at 16:46
  • OK. But none of these answers seem to handle the case of assigning a variable. let result = myFunction in any form never works. Always undefined. Just want to have the code act like a procedure language. – zakariah1 Apr 03 '23 at 20:32
  • 1
    @zakariah1 I don't think such a solution is possible for something as inherently asynchronous as network requests. I think the best solution would be to make `doRequest()` async, and later use something like `let response = await doRequest();` to think about the asynchronous nature as little as possible. – Adam Wójcik Apr 14 '23 at 14:59
  • Thanks for your suggestion! I'll. let you know how it goes. Thank you – zakariah1 Apr 17 '23 at 14:39
10

I had this problem also, found this post, and used the solution from Rishikesh Darandale (here).

The await documentation states The await operator is used to wait for a Promise. Returning the promise from a function is not required. You can just create a promise and call await on it.

async function doPostToDoItem(myItem) {

    const https = require('https')

    const data = JSON.stringify({
        todo: myItem
    });

    const options = {
        hostname: 'flaviocopes.com',
        port: 443,
        path: '/todos',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': data.length
        },
    };

    let p = new Promise((resolve, reject) => {
        const req = https.request(options, (res) => {
            res.setEncoding('utf8');
            let responseBody = '';

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

            res.on('end', () => {
                resolve(JSON.parse(responseBody));
            });
        });

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

        req.write(data)
        req.end();
    });

    return await p;
}
Gene Bo
  • 11,284
  • 8
  • 90
  • 137
David Kaufman
  • 101
  • 1
  • 2
0

You can use async-await with Promises only and Node's core https module does not have build in promise support. So you first have to convert it into the promise format and then you can use async-await with it.

https://www.npmjs.com/package/request-promise

This module has converted the core http module into promisified version. You can use this.

Sanket
  • 945
  • 11
  • 24
  • 1
    *request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142* – ruohola Jan 13 '22 at 09:21
  • -1, Also, what is the point of using thr standard `https` package if you pull in an npm package to use it with? The whole point of using `https` is to not add bloated dependencies. – ruohola Jan 13 '22 at 09:22