Question :
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?
Answer :
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
});
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;
})();