You're confusing asynchronous code with synchronous code.
You'll have to understand how async code works:
What is the difference between synchronous and asynchronous programming (in node.js)
Callbacks: Create a custom callback in JavaScript
Finally, after you've learnt a bit about async and using callbacks - here's an explanation.
const fs = require('fs');
function getRandFact() {
fs.readFile('facts.json', (err, data) => {
if (err) throw err;
const obj = JSON.parse(data);
const keys = Object.keys(obj);
const randIndex = Math.floor(Math.random() * keys.length);
const randKey = keys[randIndex];
const randVal = obj[randKey];
console.log(randVal);
return randVal;
});
}
console.log(getRandFact());
As soon as you call getRandFact(), the fs.readFile function is called and this internally starts to process the file (basically you can say it's reading and this reading is async so it takes time) but the getRandFact
the functions returns undefined
.
So, your console log prints undefined.
Then at some later point of time, the reading by the fs finishes and then it calls the callback function viz. (err, data) => {}
with the arguments so that they can now be used.
So, to solve this problem you'll have to do something like this:
const fs = require('fs');
function getRandFact(callback) {
fs.readFile('facts.json', (err, data) => {
if (err) throw err;
const obj = JSON.parse(data);
const keys = Object.keys(obj);
const randIndex = Math.floor(Math.random() * keys.length);
const randKey = keys[randIndex];
const randVal = obj[randKey];
console.log(randVal);
callback(randVal); // Notice that we called the callback function
// function and passed the random value as the parameter to it
});
}
// This will be called with the randomValue that
// will be generated and then you can use that value
function callback (randomValue) {
console.log(randomValue);
}
// We're passing the callback function
// as an argument to the getRandFact function
getRandFact(callback);