-1

I have a function that does POST request to get access tokens from an API. The function works insofar as printing the token to the console but I couldn't find a way to parse and save the access-token to a variable for using in other methods.

I've searched a lot about these on Stack Overflow, and one thing I came across was the notion of callbacks, async/await... However there is no concrete answers that show me how to RETURN the value after the request is made.

I'm getting undefined values, probably because my function is executing too fast before the request ends but nonetheless I would like to know a specific code implementation (using another callback function or something different) that allows me to get the value accessible outside these asynchronous functions.

My code is below along with a screenshot. Keep in mind this is a Lambda code for an Alexa skill

function ParseToken(obj) {    
    var string = obj + "";    
    return string;    
}

function httpRetrieveToken() {    
  var http = require("https");

  var options = {    
      "method": "POST",
      "host": "hostName",
      "path": "pathVal",
      "headers": {
        "content-type": "contentType",
        "Authorization": "Bearer token",
        "cache-control": "no-cache",
      }
  };

  var req = http.request(options, function (res) {
    var chunks = [];

    res.on("data", function (chunk) {
      chunks.push(chunk);
    });

    res.on("end", function () {
      var body = Buffer.concat(chunks);
      console.log(body.toString());
    });
  });

  req.write("stuff here");    
  req.end();
}
Jeroen Heier
  • 3,520
  • 15
  • 31
  • 32

1 Answers1

0

Parsing token

Once you have the text representing your token object you can use JSON.parse to convert it to an object:

var json = '{"token":"ABCDEFG123456789", "expires":36000}';
obj = JSON.parse(json);

console.log(obj.token);
// expected output: ABCDEFG123456789

Using Callback

You can send a callback function as parameter to the httpRetrieveToken function like:

var http = require("https");

function httpRetrieveToken(cb) {    
  var options = {    
      "method": "POST",
      "host": "hostName",
      "path": "pathVal",
      "headers": {
        "content-type": "contentType",
        "Authorization": "Bearer token",
        "cache-control": "no-cache",
      }
  };

  var req = http.request(options, function (res) {
    var _cb = cb;
    var chunks = [];

    res.on("data", function (chunk) {
      chunks.push(chunk);
    });

    res.on("end", function () {
      var body = Buffer.concat(chunks);
      var token = JSON.parse(body.toString());
      _cb(token); // Callback function
    });
  });

  req.write("stuff here");    
  req.end();
}

Then you can use function like:

httpRetrieveToken(function(token) {
  // Do something with the token
});

The reason to use a callback function is to execute it once the asynchronous process has been finished, then enclose in that callback the processes to follow with the required data.

Using Promise

Using promise object, you provide a function who executes either resolve when your process was successful or reject when you had an error. Then you set a function to be executed on sucess with then method, where you can use the token retrived by your http request.

var http = require("https");

function httpRetrieveToken() {    
  var options = {    
      "method": "POST",
      "host": "hostName",
      "path": "pathVal",
      "headers": {
        "content-type": "contentType",
        "Authorization": "Bearer token",
        "cache-control": "no-cache",
      }
  };

  return new Promise(function(resolve, reject) {
    let req = http.request(options, function (res) {
      var chunks = [];

      res.on("data", function (chunk) {
        chunks.push(chunk);
      });

      res.on("end", function () {
        var body = Buffer.concat(chunks);
        var token = JSON.parse(body.toString());
        resolve(null, token); // Callback function
      });
    });

    req.on("error", function(err) {
      reject(err);
    });

  });
}

httpRetrieveToken().then((err, token) => {
  if(err) console.log(err);

  // Do something with token
});
Cristian Colorado
  • 2,022
  • 3
  • 19
  • 24
  • Thank you very much for this answer, Cristian. I'm certain they work but I can't figure how to call the function which returns or say prints the token. I'm new to javaScript so it's the first time I'm working with functions that have syntax like httpRetrieveToken(function(token) { });... I would understand how to invoke functions like functionA() {some stuff} so my question is what will I say to invoke the callback function? do i say just httpRetrieveToken() or httpRetrieveToken("with some stuff here")? Thank you very much though! – Abenezer Ayana Mar 01 '19 at 22:21
  • The idea is that you can send as a parameter a function and use the parameter to call the function. Say you define var processToken = function(token) { console.log(token)}, then you invoke httpRetriveToken(processToken). In the body of httpRetriveToken you can use the parameter to execute processToken anytime you want, and as many times you want. but the idea is to call it once your async call has been completed, for intance when your http call has been answer. – Cristian Colorado Mar 01 '19 at 22:37
  • I'm getting a type error, TypeError: cb is not a function after doing your callback version. Is there any fix for that, as I assume I'm passing a function. – Abenezer Ayana Mar 02 '19 at 00:07
  • Oh, that is because the scope of cb function, cb function is reachable at httpRetrieveToken and response function provided to http.request call. But then inside there is a third level, res.on("end", function... that is not reachable. Easiest way is to make a local variable to extend the reach. Though there maybe another solution. – Cristian Colorado Mar 02 '19 at 00:45