0

I am trying to read all image files in the folders recursively then return data to the browser. However, the data is not returned to the outside of function even the data is displayed on console inside the function. How can I fix it? Appreciate it for anyhelp! Here is my code:

    var express = require('express');
  var app = express();
  var http = require('http');
  var fs = require('fs');
  var path = require("path");
  //var flist = require('./fs-readdir-ar-fp.js');
  app.use(express.static(__dirname + "/public"));

  var filelist = function(dir) {      
    fs.readdir(dir,function(err,list){
        list.forEach(function(file){
             var file2 = path.resolve(dir, file);
            fs.stat(file2,function(err,stats){
                if(stats.isDirectory()) {
                    filelist(file2);
                }
                else {                  
                    //console.log(file2); // <-- data is displayed on console

                }
            })            
        })      
    })   
};
  flistArr = filelist('images');
  console.log(flistArr); // <-- No data is displayed on console???

var server = http.createServer(function(req, res){
    res.writeHead(200,{'Content-Type': 'application/json'});
    res.end(JSON.stringigy(flistArr));
});

app.listen(3000);
console.log('3000 is the magic port');
Henry
  • 21
  • 1
  • 1
  • 5
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – baao Apr 22 '18 at 21:25
  • Well firstly, why would you expect something from `filelist` when it doesn't actually return anything? Secondly, *why* doesn't it return something? If you can understand that then you'll understand how to solve the problem. – James Apr 22 '18 at 21:26
  • You are right James. Actually I tried a return right below "else" but did not get anything returnned then I removed it. Not sure how to fix it. – Henry Apr 28 '18 at 22:07

1 Answers1

0

The filelist function doesn't return anything - there are no return statements in there.

You're using the asynchronous APIs from the Node standard library so you've had to pass a callback to each function and that's where you're logging to the console e.g.

var result = fs.stat(file2, function(err,stats){
    console.log("I am a callback function")
})
// result is undefined - fs.stat doesn't return anything

Try using the *Sync versions of the functions i.e. https://nodejs.org/docs/latest/api/fs.html#fs_fs_readdirsync_path_options and https://nodejs.org/docs/latest/api/fs.html#fs_fs_statsync_path to avoid having to deal with asynchronous details for now.

Edit:

An example of the filelist function, written using the *Sync functions from the standard library:

const fs = require('fs');                                                          
const path = require("path");                                                      

function filelist(dir) {                                                           
    let dirListing = fs.readdirSync(dir)                                           
    let filesAndSubDirListings = dirListing.map(function(file){                    
        var fullPathToFile = path.resolve(dir, file);                              
        let stats = fs.statSync(fullPathToFile)                                    
        if(stats.isDirectory()) {                                                  
            return filelist(fullPathToFile);                                       
        }                                                                          
        else {                                                                     
            return fullPathToFile;                                                 
        }                                                                          
    })                                                                             
    return filesAndSubDirListings.reduce((x, y) => ( x.concat(y)), [])             
}

It's more or less the same as yours, except that we skirt the callbacks by using e.g. statSync and getting the return value. We need to reduce the result down to a single array because we return the result of recursively calling filelist. To see what it does, take it out and see what the return looks like.

grahamlyons
  • 687
  • 5
  • 15
  • Thanks grahamlyons! Actually I tried a return from inside the function but did not get anything returned. I also tried the callback function after watch others examples on youtube but have not been successful for my code. I used to be a developer using the old languages and python but new to node js. Can you please show me how I should modify my code in full? – Henry Apr 28 '18 at 21:41
  • Thanks grahamlyons! Can you please show me the async version of the full code? – Henry May 05 '18 at 16:49