Reputation: 1562
Given a directory containing markdown files, i.e.
myDir
|- fileA.md
|- fileB.md
|- fileC.md
|- fileD.md
I'm trying to create an array of these files, by also stripping the file extension.
I'm trying with this:
var mdFiles = fs.readdir('myDir', (err, files) => {
const filesNoExt = []
files.forEach( file => {
filesNoExt.push(file.slice(0, -3)
})
return filesNoExt
});
console.log(mdFiles)
but the result of the console.log
command is undefined
.
If I modify this script like this (so, by adding a console.log
inside the readdir
function):
var mdFiles = fs.readdir('myDir', (err, files) => {
const filesNoExt = []
files.forEach( file => {
filesNoExt.push(file.slice(0, -3)
})
console.log(filesNoExt)
});
console.log(mdFiles)
here is what I get:
undefined
[
'fileA',
'fileB',
'fileC',
'fileD'
]
The first line is undefined
exactly like before, but then it is also printed the result of the console.log
inside the function, which shows that the filesNoExt
array is correctly populated with the stripped filenames.
How can I correctly return the filesNoExt
array from the mdFiles
function, so that I can access its content also from outside?
Upvotes: 0
Views: 440
Reputation: 6597
The callback you passed to fs.readdir
happens asynchronously (after the call stack empties), so there is no way that you can get its return value like that. In fact, the return value is ignored. You can use this:
fs.readdir('myDir', (err, files) => {
const filesNoExt = [];
files.forEach( file => {
filesNoExt.push(file.slice(0, -3)
});
console.log(mdFiles)
});
Or you can use promises like this:
(async ()=>{
const mdFiles = await fs.promises.readdir('myDir');
files.forEach( file => {
filesNoExt.push(file.slice(0, -3)
});
console.log(mdFiles);
})();
If you are doing other asynchronous actions (e.g. using setTimeout
) you should not use the synchronous variants of fs
functions (like fs.readdirSync
) because they will block the program (main thread) while executing the action.
Upvotes: 1
Reputation: 35560
The reason it's not working is because readdir
is an asynchronous function, which means it runs in parallel to the rest of your code. If you want to block execution, use readdirSync
:
var mdFiles = fs.readdirSync('myDir');
const filesNoExt = [];
mdFiles.forEach(file => {
filesNoExt.push(file.slice(0, -3)
});
console.log(filesNoExt);
Upvotes: 3