2

I cannot figure out how to get a variable from a node.js module. I'm creating a module that will interface with an authentication mechanism, and currently it only returns a token. I need this token in the main.js, as I will be calling other modules, and passing this token for authentication.

//auth.js
var request = require("request");
var authModule = {};
var authToken = "";

var options = {
    method: 'POST',
    url: 'https://dummy.url/oauth/token',
    headers: {
        'authorization': 'Basic secretkeystring',
        'accept': 'application/json',
        'content-type': 'application/x-www-form-urlencoded'
    },
    form: {
        grant_type: 'password',
        username: 'indegomontoya',
        password: 'sixfingeredman'
    }
};

authModule.getToken = function getToken(){
    request(options, requestToken);
};

function requestToken (error, response, body) {
    if (error) throw new Error(error);
    authToken = response.body.toString().split('\n')[1].split(":")[1].split('"')[1];
    console.log("auth.js says: " + authToken);
    // ^^ this works, and spits out the correct token to the console
    return authToken;

};

module.exports = authModule;
module.exports.token = authToken;

And here is my main.js:

//main.js
var auth = require("./auth.js");
var token;

token = auth.getToken();
console.log("main.js says :"+ token);
// ^^ comes back undefined

I've seen examples of sending a variable from main.js to module.js, but I need to do the opposite. Any help is greatly appreciated!

EDIT: typo in code.

  • I believe, since it's async, you'll want a callback. http://callbackhell.com/ helped me a lot in understanding them. – Drazisil Nov 19 '15 at 14:56

3 Answers3

2

Try passing a hash instead.

module.exports = {
  module: authModule,
  token: authToken
}

var gcdm = require("./gcdm.js");

gcdm.module();
gcdm.token;
Linus Oleander
  • 17,746
  • 15
  • 69
  • 102
1

It appears that the request module (from here), is asynchronous in nature, meaning that it can take any length of time to return its data. This means that you may need to use a callback when using the getToken method.

Currently, your main.js app does not give suffiecient time for the auth.js module to fetch the token data. It requests the token and then in the same breath (or tick of the processor) it tries to print it to the console. To get around this problem, you need to utilise callbacks.

I would probably adjust your two auth module methods like so:

authModule.getToken = function getToken(callback){

    request(options, function(error, response, body){

        if (error) throw new Error(error);

        callback( requestToken(body) );

    });
};

function requestToken (body) {

    authToken = response.body.toString().split('\n')[1].split(":")[1].split('"')[1];

    return authToken;

};

Also, remove this uneeded line, as your callback will be the delivery mechanism back to your main app:

module.exports.token = authToken;  // remove this

You would then use something like this to get the token in your main app:

gcdm.getToken( function (token) {

  console.log('main.js says :' + token);

});

You may want to look a bit more into Asynchronous Programming in JavaScript. It's a key ingredient in the NodeJS toolbox.

shennan
  • 10,798
  • 5
  • 44
  • 79
  • I think the main problem OP has is that he doesn't understand how `export` works in node. Good answer tho, +1 – Linus Oleander Nov 19 '15 at 14:50
  • @Oleander Cheers. It's possible, but there is nothing he is doing which is technically 'breaking' the export functionality. His `module.exports` variable has already been set to an arbitrary object, so adding `module.exports.token` is not currently hurting it (though certainly could do in the future if his namespaces change - hence my suggestion that he remove that line). – shennan Nov 19 '15 at 14:56
0

@shennan thank you very much! You were right on track, and you are correct, request is async. I'm fairly new to node.js, so thanks for bearing with me, and am still trying to wrap my head around callbacks. (thanks @Drazisil for your link to callbackhell.com)

Your answers got me int he right direction, and I ended up with this:

//auth.js
var request = require("request");
var authModule = function () {};
var authToken = "";

var options = {
    method: 'POST',
    url: 'https://dummy.url/oauth/token',
    headers: {
        'authorization': 'Basic secretkeystring',
        'accept': 'application/json',
        'content-type': 'application/x-www-form-urlencoded'
    },
    form: {
        grant_type: 'password',
        username: 'indegomontoya',
        password: 'sixfingeredman'
    }
};

authModule.getToken = function getToken(callback){

    request(options, function(error, response, body){
        if (error) throw new Error(error);
        authToken = response.body;
        callback( requestToken(body) );
    });
};

function requestToken (body) {
    return authToken;
};

module.exports = authModule;

And:

//main.js
var auth = require("./auth.js");
var authTokenData;

function parseAuthJson(data) {
    var jsonData = JSON.parse(data);
    return jsonData;
}

auth.getToken( function (authTokenData) {
    var jsonData = parseAuthJson(authTokenData);
    console.log(jsonData.access_token);
});

I gathered help about parsing the JSON here.

Thanks for your help!

Community
  • 1
  • 1