0

With consideration of the following code-block, how would one go about having loadConfig() return the JSON config object?

function loadConfig(){
  fs.readFile('./config.json', 'utf8', function (err, data){
    if (err) throw err;
    var config = JSON.parse(data); 
  });
  return config;
};

The returned config is undefined as the variable config is outside the scope of the loadConfig() function, yet if the the return statement is located inside the readFile anonymous function, it doesn't fall through to loadConfig(), and seemingly only breaks the nested anonymous function.

Another attempt has been made to resolve this by saving the anonymous function in a variable which is then returned by the main function loadConfig, but to no avail.

function loadConfig(){
  var config = fs.readFile('./config.json', 'utf8', function (err, data){
    if (err) throw err;
    var config = JSON.parse(data);
    return config;
  });
  return config;
};

The question stands; given situation sketched above, how would one make loadConfig() return the config JSON object?

lux
  • 411
  • 7
  • 17

4 Answers4

3

Just define/use a promise:

function loadConfig(){
  return new Promise(function(resolve, reject) {
    fs.readFile('./config.json', 'utf8', function (err, data){
      if (err) reject(err);

      var config = JSON.parse(data);
      resolve(config); 
    });
  })
};

and to use it:

loadConfig().then(function(config) {
  // do something with the config
}).catch(function(err){
  // do something with the error
});
caisah
  • 1,959
  • 1
  • 21
  • 31
  • this is best way to do it, or use success – Abhinav Mar 17 '17 at 18:26
  • So I cannot just have a global variable with the config object which I can refer to whenever I want; I need to use the configVar.then(...); to access the config object I take it as I cannot just return the input to the "then function". Am I correct in this? – lux Mar 17 '17 at 19:14
  • You can have a global variable, but because the action is asynchronous you don't know when that variable is being populated. By using `then` you avoid this, because as soon as the config is set, you can use it in the next function. This is called a promise or a future (in other languages) and is the idiomatic way of dealing with asynchronous actions. You are basically returning a function which you can use it immediately after it has some result. Please read more here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – caisah Mar 17 '17 at 19:19
0

Simple answer is you can't.

These are async call, which mean your return statement will not wait for your response, it will continue to execute. Hence when you call function your return statement is fired first and then you receive the response.

Instead, use success callback function for your operation and not return value..

Abhinav
  • 1,202
  • 1
  • 8
  • 12
0

Use readFileSync instead of readFile. Since readFile is an async mthod.

function loadConfig(){
  var fileContent = fs.readFile('./config.json', 'utf8').toString();
  return fileContent?JSON.parse(fileContent):null;
};
ajai Jothi
  • 2,284
  • 1
  • 8
  • 16
-2

You can also use the synchronous version of readFile or yes, Promise is the other solution. Doc here: https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options

Tom
  • 13
  • 2