I'm trying to read an object from a JSON file and use it in the rest of the code. For that, I used "fs" with node.js. But it seems that javascript runs the selected part at the end.
const fs = require('fs');
let objList = [];
/* vvv Selected Part vvv */
fs.readFile("sample.json", (error, file) => {
if (error) {
console.log("ERROR!");
throw error;
}
console.log("here");
objList.push(JSON.parse(file.toString()));
console.log("> ", objList);
});
/* ^^^^^^^^^^^ */
console.log(">> ", objList);
The ouput is:
>> []
here
> [ { name: 'name goes here', age: 30 } ]
Why does it happen and how can I fix that? Beside, Is there a better way to implement this?
There's nothing wrong with how your code works, it's not a bug
The function fs.readFile reads a file asynchronously, meaning it's not blocking so your program continues, and the function you pass as the second parameter is a callback that is fired once reading the file is finished.
There are a couple of ways you can deal with it:
One of them is to use the fs.readFileSync function, which does the same thing but synchronously, meaning it stops your program until reading the file is done. This is usually not recommended since reading files may take time and it's better to do it in a non-blocking way.
It would look something like
const fs = require('fs');
let objList = [];
const file = fs.readFileSync("sample.json", {encoding:'utf8'})
objList.push(JSON.parse(file.toString()))
console.log(">> ", objList);
You can add a try/catch block to catch errors as well
The other method is to use an async function and the await keyword to wait for your file to be read use fs.promises like so:
const fs = require('fs');
async function myFunc() {
let objList = [];
const file = await fs.promises.readFile("sample.json","utf8")
objList.push(JSON.parse(file.toString()))
console.log(">> ", objList);
}
myFunc()
Which uses a Promise that you can wait until it's finished