0

In my code I try to assign a value to json variable to return it after (because I can't return it from the anon. function).

As my function is async, because it sends requests (maybe someone knows how to make it sync? I didn't plan to make it asynchronous), I've added await before the request (https.get).

I've been trying to get value from the Promise, but it's always undefined, even though I've awaited the async function.

Here's a code:

async function get_users() {
    const https = require('https');
    var token = '...';
    var json = undefined;

    await https.get('...', (resp) => {
        let data = '';

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

        resp.on('end', () => {
            json = JSON.parse(data)['response']['items'];
        });
    }).on("error", (err) => {
        console.log("Error: " + err.message);
    });

    return json;
}

get_users().then(function(result) {
    console.log(result);
});
user7637745
  • 965
  • 2
  • 14
  • 27
KeterDev
  • 7
  • 1
  • 6
  • 1
    I searched for a bit and don't think `https.get` returns a promise. `await` will not wait for the request to finish. – ASDFGerte Jul 01 '18 at 14:07
  • The problem is that `json` is undefined when I return it. What's the reason? – KeterDev Jul 01 '18 at 14:10
  • https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call is the issue - your await will finish once the current execution environment finishes its tasks, instead of when the request finishes. – ASDFGerte Jul 01 '18 at 14:12
  • So what do I have to do? – KeterDev Jul 01 '18 at 14:14

2 Answers2

1

Return a Promise and resolve it, when the end event is called, otherwise reject it in case of an error occurred:

async function get_users() {
  const https = require('https');
  const token = '...';

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

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

      resp.on('end', () => {
        let json;

        try {
          json = JSON.parse(data)['response']['items'];          
        } catch (e) {
          reject(e);
        };
        resolve(json);
      });
    }).on("error", err => reject(err));
  });
}

get_users().then(result => console.log(result));
user7637745
  • 965
  • 2
  • 14
  • 27
  • 1
    This blows up when `data` cannot be parsed as JSON. You should do only `resolve(data);` in the end callback, and do any processing in promise `then` callbacks or after `await` where exceptions will be properly handled. – Bergi Jul 01 '18 at 14:25
  • @Bergi, thank you! If you would want to process the `data` in the `get_users()` function, what would be the best approach in this case in you opinion? – user7637745 Jul 01 '18 at 14:44
  • 1
    `return new Promise(…).then(data => JSON.parse(data)['response']['items']);` or `const data = await new Promise(…); return JSON.parse(data)['response']['items'];` – Bergi Jul 01 '18 at 14:47
0

Please refer my below code.I had issues with getting responses from Promises too.But i finally got it to work.Here's the code:

var output;
var rp = require('request-promise-native');
var myJSONObject = {
  "inputs": [{
    "name": "<name>",
    "value": < value >
  }]
};
var orchName = 'TEST05';
postData = JSON.stringify(myJSONObject);
return networkCall(postData, orchName).then((response) => {
  console.log('response is' + response)

}).catch((response) => {
  console.log(`ERROR: ` + response);
});

function networkCall(postData, orchName) {
  return new Promise((resolve, reject) => {
    var options = {
      method: 'post',
      uri: '<URL>',
      body: postData,
      auth: {
        'user': 'usr',
        'pass': 'pwd'
      },
      json: true
    };
    return rp(options)
      .then(body => {
        var response = body;
        resolve(response);
      })
      .catch(err => {
        console.log('FAILED' + err);
        reject(err);
      });
  });
}

This way your code can run in Synchronous Flow.If the return value is undefined,then,what might have probably happened is that the calling function would have finished executing even before the called function returns its response.But the above approach would work just fine.

vasanth kumar
  • 235
  • 1
  • 3
  • 13
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Jul 01 '18 at 14:25