I ran into the same problem, and based on the answers provided in this post, I solved this with Promises , which seem to be perfect in this situation:
router.get('/', (req, res) => { var viewBag = {}; // It just my little habit from .NET MVC ;) var readFiles = new Promise((resolve, reject) => { fs.readdir('./myfiles/',(err,files) => { if(err) { reject(err); } else { resolve(files); } }); }); // showcase just in case you will need to implement more async operations before route will response var anotherPromise = new Promise((resolve, reject) => { doAsyncStuff((err, anotherResult) => { if(err) { reject(err); } else { resolve(anotherResult); } }); }); Promise.all([readFiles, anotherPromise]).then((values) => { viewBag.files = values[0]; viewBag.otherStuff = values[1]; console.log(viewBag.files); // logs eg [ 'file.txt' ] res.render('your_view', viewBag); }).catch((errors) => { res.render('your_view',{errors:errors}); // you can use 'errors' property to render errors in view or implement different error handling schema }); });
Note. you donβt need to push the found files into the new array, because you already get the array from the fs.readdir () 'c callback. According to node docs :
The callback receives two arguments (err, files) , where the files are an array of file names in the directory, excluding ".". and "..".
I believe that this is a very elegant and convenient solution, and, most importantly, it does not require entering and processing new modules into your script.
source share