I'm new to javascript so i'm sorry if this has been asked before.
I have this function which i use to read json files.
const jsonfile = require('jsonfile');
function readData(fileName: string, callback) {
jsonfile.readFile(".\\data\\" fileName ".json", 'utf8', function (err, data) {
if (err) console.error(err)
callback(null, data);
})
}
Then I call it using this:
// Read JSON files
var fileList = ["guides"];
var files = {};
for (let i = 0; i < fileList.length; i ) {
readData(fileList[i], function (err, result) {
if (err) throw err;
files[i] = result;
})
}
but when I:
console.log(files['guides']);
it returns undefined
. Can anyone help me fix this? Thank you very much.
CodePudding user response:
Callback function of the jsonfile.readFile
function is called asynchronously and your console.log
statement is executed synchronously.
Asynchronous code is executed after the synchronous execution of your javascript code has ended; as a result, your console.log
statement is logging files['guides']
before guides
property is added in the files
object. This is why you get undefined.
Following code example shows this problem in action:
let a = 1;
setTimeout(() => {
a = 2;
}, 100);
console.log(a);
Above code snippet outputs 1
because the callback function of setTimeout
is invoked asynchronously, i.e. after the console.log(a)
statement has been executed and at the time of execution of console.log
statement, value of a
is 1
.
Solution
To make sure that you log files["guides"]
after all the files have been read and files
object has been populated, you could return a promise from the readData
function.
Following code shows how you could create a promise wrapper around readData
function:
function readData(fileName) {
return new Promise((resolve, reject) => {
jsonfile.readFile(".\\data\\" fileName ".json", 'utf8', function (err, data) {
if (err) reject(err);
else resolve(data);
})
}
};
Now you can call the above function as:
Promise.all(fileList.map(filePath => readData(filePath)))
.then(dataFromAllFiles => {
console.log(dataFromAllFiles);
})
.catch(error => console.log(error));
Useful Links: