Search code examples
javascriptnode.jseventemitternode-request

How do I use part of a returned object from an API request as what the function returns?


I have been researching and testing how to do API calls in node js. I'm currently trying to use part of a JSON object that gets returned from an API call in a module to return a Token.

var request = require("request");
var timestamp = require("unix-timestamp");
var jwt = require("jsonwebtoken"); 
var EventEmitter = require("events").EventEmitter;

timestamp.round = true;

//create current unix timestamp
var current = timestamp.now();

//create unix experation time
var experation = timestamp.add(current, "+5m");

//create header
var header = {"header"}

//create payload
var payload = {
   "iss": process.env.CKEY,
   "aud": "https://iformbuilder.com/exzact/api/oauth/token",
   "exp": experation,
   "iat": current
};

var signature = process.env.SKEY;

//Create assertion
var assert = jwt.sign(payload, signature);
var grant = 'urn:ietf:params:oauth:grant-type:jwt-bearer';

//set the options
var options = { method: 'POST',
  url: 'https://iformbuilder.com/exzact/api/oauth/token',
  qs: {
     grant_type: grant,
     assertion: assert 
  },
  headers: { 
     'content-type': 'application/x-www-form-urlencoded',
     'cache-control': 'no-cache' 
  }
};

var data = {};
var tkn = new EventEmitter();

module.exports = {
    token: function() {
        request(options, function (error, response, body) {
            if (error) throw new Error(error);
            console.log(body);
            tkn.body = body;
            tkn.emit('update');
         });

        tkn.on('update', function(){
            data = JSON.parse(tkn.body);
            return data.access_token;
        });
    }
}

The problem is that I can only use the returned item within the scope of tkn.on. I can nesting another API call within to use the token. However, I would like to use it without having to use the same code over again. The only solution that I can get to work is writing to a file. I'm wondering if I'm even going about this the right way. I can't seem to find any good source online to help me with this and maybe I'm asking the wrong question.


Solution

  • You have to use a callback (or promise) to get the value. Below is an example with callbacks I'll let you research promises. I would say, understand it with callbacks first then move on to promises.

    someOtherModule.js

    var tokenGetter = require('./tokenGetter');
    
    function doSomethingWithToken(accessToken){
        //Do what you want with the token here
    }
    
    tokenGetter.token(doSomethingWithToken);
    

    tokenGetter.js

    module.exports = {
        token: function(callback) {
            request(options, function (error, response, body) {
                if (error) throw new Error(error);
                console.log(body);
                tkn.body = body;
                tkn.emit('update');
            });
    
            tkn.on('update', function(){
                data = JSON.parse(tkn.body);
                callback(data.access_token);
            });
        }
    }
    

    The reason you have to do this is because with asynchronous operations, you do not know when you will get a response. The code is no longer linear in the same way it was before.

    You have to adjust your code to continue its operations WHEN you get a response instead of AFTER you do the operation.