In NodeJS, global variable in my app.js file is undefined in another file

3

I'm in a project using NodeJS, and its Express framework.

In the main file app.js I call a function to read a file, and assign it to a global variable:

global.google_sheet_credentials = readFileCredentials("spread_sheet.txt");

The function code readFileCredentials is:

readFileCredentials = function(file){
    fs.readFile('data-source/credentials/'+file, 'utf8', function(err, data){
        if(err){
            console.log("Could not open file: %s", err);
        }else{
            console.log(data);
            return data;
        }
    });
};

module.exports = readFileCredentials;

After that, I redirect to another file:

rek('dashboards/ti/main_it');

In this file main_it.js , I try to use this global variable google_sheet_credentials :

console.log(google_sheet_credentials);

However, it warns that it is undefined, can someone explain the reason for it, and a way for me to get the right result?

    
asked by anonymous 27.04.2016 / 13:47

2 answers

3

This function is asynchronous, ie this return is not used the way you think.

You need to use a callback (or via Promise as suggested in another answer). So you can only rely on the value set in this global.google_sheet_credentials when the callback is called.

One suggestion would look like this:

readFileCredentials = function(file, cb){
    var _path = 'data-source/credentials/' + file;
    fs.readFile(_path, 'utf8', function(err, data){
        if(err){
            console.log("Could not open file: %s", err);
        }
        cb(err, data); 
    });
};

module.exports = readFileCredentials;

and then use this:

readFileCredentials("spread_sheet.txt", function(err, data){
    global.google_sheet_credentials = data;
    // agora a variável está setada. Se precisares de correr outro código tens de o ter aqui dentro, ou chamando funções a partir daqui
});
    
27.04.2016 / 15:46
3

Clearly the problem with your code is asynchronous. Promises can solve your problem:

function readFileCredentials(file) {
    return new Promise(function(resolve, reject) {
        fs.readFile('data-source/credentials/' + file, 'utf8', function(err, data){
            if (err) {
                console.log("Could not open file: %s", err);
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
};

module.exports = readFileCredentials;

In the call, just use then to continue the Promise process:

readFileCredentials("spread_sheet.txt").then(function(googleSheetCredentials) {
    global.google_sheet_credentials = googleSheetCredentials;
});

Update:

Depending on which link was passed, try modifying your App code to work as follows:

var App = (function(){

    // Method Construct, your objetive is loading modules and utils that will be used in this project.
    function App() {
        this.define_global_utils(function() {
          this.define_global_modules();
        }.bind(this));

        this.init();
    }

    // Method responsible for initiating the application.
    App.prototype.init = function(){
        this.load_modules();
    };

    // Method responsible for importing the modules used in this project.
    // The modules were imported globally, that is, can be used in anywhere in the code.
    App.prototype.define_global_modules = function() {
        global.rek = require('rekuire');
        global.fs = require('fs');
    };

    // Method responsible for imported the utilities.
    App.prototype.define_global_utils = function(callback){
        global.readFileCredentials = rek('data-source/utils/readFileCredentials');

        readFileCredentials("spread_sheet.txt", function(err, data){
            global.google_sheet_credentials = data;
            callback();
            // agora a variável está setada. Se precisares de correr outro código tens de o ter aqui dentro, ou chamando funções a partir daqui
        });
    };

    // Method responsible for loading the dashboards.
    App.prototype.load_modules = function(){
        rek('dashboards/implantation/main_implantation');
    };

    return App;
})();
    
27.04.2016 / 15:37