0

I'm working on a Node.JS function that has to do 2 things - request some data from an API, process it and return it to the caller.

The trouble is that the API call (using https module) is asynchronous and my function returns before the API call returns the data. Here is my code:

const https = require('https');

const options = {
  hostname: 'tmp-s.s3.amazonaws.com',
  port: 443,
  path: '/groups.json',
  method: 'GET',
};

const MyHandler = {
  handle(handlerInput) {
    var group_name;
    api_call = function() {
      return new Promise( (resolve, reject) => {
        req = https.request(options, function(res){
          var data = '';

          //console.log('statusCode:', res.statusCode);
          //console.log('headers:', res.headers);

          res.on('data', function(d){ data += d; });

          res.on('end', function(){
            console.log(data);
            var _groups = JSON.parse(data);
            var _group_name = _groups[1].name;
            console.log("In res.on(): " + _group_name);
            resolve(_group_name);  // RESOLVE the promise
          });
        });
        req.end();
      });
    }

    api_call().then((value) => {
      group_name = value; // I have to return this _value_ from MyHandler.handle()
      return group_name;  // This returns from the then()-function, not from MyHandler.handle()
    });

    return group_name;  // This returns before group_name is set :(
  }
}

// Just for testing - something else calls MyHandler.handle()
console.log("In main(): " + MyHandler.handle("blah"));

The above prints:

In main(): undefined
In res.on(): Group 1

What I want instead is the reversed sequence and no undefined results:

In res.on(): Group 1
In main(): Group 1

Someone closed my previous question as a duplicate for This question but I still can't make it work. Tried to add the Promise but still unable to wait for the completion in my handle() function. I have no control over the caller of MyHandler.handle() - it calls my function and I have to return the API call result. I can't change anything in the caller.

I would much prefer if someone could help me with my sample code rather than closing it again as a duplicate of something remotely similar that I can't make work. Please :)

MLu
  • 1,218
  • 2
  • 15
  • 28
  • Please don't repost questions. The duplicate was there to point out that just as someone did respond here that you cannot `return` a value here. Instead you resolve the promise and then continue the promise chain. Instead of posting new questions you should clear up where you actually think you need to use this value, so you can at least be directed to how to chain the result into the function call that actually needs it. But that's actually what the content on the duplicate says when you take the time to read and learn it. Make changes to your previous question if you still don't understand. – Neil Lunn Jun 03 '18 at 14:13

1 Answers1

0

Instead returning group_name value, return promise in MyHandler.handle:

return api_call();

And then you have to wait as well:

MyHandler.handle("blah").then(value => {
    console.log(value);
});

I hope it helps :)

Kamil
  • 424
  • 4
  • 8
  • Thanks but I can't wait in the caller. I have no control over what the caller does - it's AWS Alexa service calling my `MyHandler.handle()`. I can't change the caller, somehow I have to wait in the `handle()` function before returning. – MLu Jun 03 '18 at 11:54
  • 1
    Does AWS Alexa service work only in synchronous way? Could you point me to official documentation you rely on? – Kamil Jun 03 '18 at 12:12
  • thanks for the hint, turns out Alexa API does accept a returned Promise. :) – MLu Jun 11 '18 at 00:28