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

Asked

Viewed 3,375 times

4

I am in a project using Nodejs, and its Express framework.

In the main archive app js. i call a function in order to read a file, and assign to a global variable:

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

The code of the function readFileCredentialls 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);

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

  • 1

    You can create a module to read the .txt and import it into the file you want.

  • That one readFileCredentials is synchronous?

  • It is a function that takes the name of the file, and returns the contents of that file, I can’t tell you if it is synchronous or asynchronous.

  • You can put the code of that function here?

  • I put the code in the question.

2 answers

4


This function is asynchronous, that is to say return is not used the way you think.

You have to wear a callback (or via Promise as suggested in another reply). Thus, you can only count on the value set in that global.google_sheet_credentials when the callback is called.

A suggestion would be so:

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 it like 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
});
  • Thank you for your answer, but unfortunately I’m not working. I created a repository in git, and imported the part that is giving the problem, to get a better view: https://bitbucket.org/JGonczoroski/teste . When you can take a look

  • @Jonathangonczoroski where you need google_sheet_credentials? I don’t see that in your code

  • In the file that is: dashboards/implantation/pushers/teste.js , la is a print of that variable

  • @Jonathangonczoroski, why don’t you use the normal logic of doing requires in the files because you’re using the global space? This was one of the great novelties and advantages of Node.js...

  • Yes, I took a project in this structure, and I must modify it, but I started learning now Nodejs, so I followed the structure that was already there. As for your tip, you’re saying that instead of me trying to put the contents of the file into a global variable, I should use a require?! But which file should I import anywhere?

  • @Jonathangonczoroski, because I think you should use the common way in the Node. Take a look here: https://github.com/mootools/website/blob/master/build/docs.js is from the Mootools website where I participate. The idea is to require all the modules you need in a given file. All requires to the head, to organize code and the Node makes each require stay in memory and only be loaded once.

  • So you have this Docs.js that matters the modules you want to use in the project. However, when you want to use any of these modules already imported, do you import Docs.js? I didn’t find any . js import Docs.js in order to use them

  • 1

    @Jonathangonczoroski no. Each file matters what you need. In some cases I require exactly the same thing in different files. The rule is to require the files/modules that this file needs.

  • Got it, in my case, I wouldn’t need to use the require('fs) in that file app.js, because I only use file manipulation readFileError right? But it helps me in my problem of getting the file information before giving indefinite ?

Show 4 more comments

3

Clearly your code problem is with asynchrony. 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;

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

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

Updating:

As the link that was passed, try to modify 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;
})();
  • Thank you for your answer, but unfortunately I’m not working. I created a repository in git, and imported the part that is giving the problem, to get a better view: https://bitbucket.org/JGonczoroski/teste . When you can take a look. The code is with Sérgio’s solution, but I also tested yours, and it didn’t work either. It’s probably something related to my code, so if you could help me, I’d appreciate it

Browser other questions tagged

You are not signed in. Login or sign up in order to post.