0

This is my first day in NodeJS and I need to write a small a program that checks for a certain word in a list of files and folders and prints out an array of files that contains this word,

I have written the program but unfortunately i wrote it in a synchronous way, not knowing that NodeJS is asynchronous, after searching the internet I found out the problem but I can't still figure out the solution.

Here is the code that I wrote:

// Get needed arguments for running the script
// USAGE: node search [EXT] [TEXT]
var args = process.argv.slice(2);

if(args[0].length == 0 && args[1].length == 0) { 
    console.log("USAGE: node search [EXT] [TEXT]");
    process.exit();
}

ext_args = args[0];
word_args = args[1];

var fs = require('fs'); // include file reader module
var path = process.cwd(); // get current path of script
var fileList = getFiles(path, ext_args, word_args);
console.log(fileList);
console.log("end");
/*
Function that get files recursively in a current script path
*/
function getFiles(path, ext, word) {
    var fileList = [];
    fs.readdir(path, function(err, items) {
        for (var i=0; i<items.length; i++) {
            var currentFile = items[i];
            var itemPath = path + "\\" + currentFile;
            if(fs.lstatSync(itemPath).isDirectory()) {              
                return getFiles(path + '\\' + currentFile, ext, word);
            } else {
                if(currentFile.endsWith(ext)) {
                   fileList.push(checkString(itemPath, word));
                } else {
                }
            }
        }
    });
    return fileList;
}

/*
 Function that checks if the word exist in the text file
*/
function checkString(filePath, word) {
    fs.readFile(filePath, 'utf8', function(err, data) {
        //console.log("> Checking String");
        if(err) throw err;
        if(data.indexOf(word) >= 0) {           
            return filePath;
        } else {          
        }

    })
}

When I print fileList I get it as an empty array. Can you show me how to write the recursive function in a proper way?

10
  • so what you are trying to do is check if a file with a certain word in its filename, within a directory or subdirectories exists? Commented Mar 23, 2018 at 20:27
  • fileList.push(checkString(itemPath, word)); uses an async function which is why its empty Commented Mar 23, 2018 at 20:27
  • checkString needs to use fs.readFileSync or you need to redesign all your code to async. Commented Mar 23, 2018 at 20:28
  • @Noface I want to get a list of all files in directories and directories that contains certain word Commented Mar 23, 2018 at 20:29
  • 1
    it is unecessary to write this code from scratch when a substantial amount has already been done Commented Mar 23, 2018 at 20:32

1 Answer 1

1

You need to use Async/await or promise to handle the asynchronous I/O operation as below:

// Get needed arguemnts for running the script
// USAGE: node search [EXT] [TEXT]
var args = process.argv.slice(2);

if (args[0].length == 0 && args[1].length == 0) {
    console.log("USAGE: node search [EXT] [TEXT]");
    process.exit();
}

ext_args = args[0];
word_args = args[1];

var fs = require('fs'); // include file reader module
var path = process.cwd(); // get current path of script
getFiles(path, ext_args, word_args).then((fileList) => {
    console.log(fileList);
    console.log("end");
});
/*
Function that get files recursivly in a current script path
*/
function getFiles(path, ext, word) {
    var fileList = [];
    return new Promise((resolve, reject) => {
        fs.readdir(path, (err, items) => {
            for (var i = 0; i < items.length; i++) {
                var currentFile = items[i];
                var itemPath = path + "\\" + currentFile;
                if (fs.lstatSync(itemPath).isDirectory()) {
                    resolve(getFiles(path + '\\' + currentFile, ext, word));
                } else {
                    if (currentFile.endsWith(ext)) {
                        fileList.push(checkString(itemPath, word));
                    } else {}
                }
            }
        });
        resolve(fileList);
    })
}

/*
 Function that checks if the word exist in the text file
*/
function checkString(filePath, word) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, 'utf8', (err, data) => {
            //console.log("> Checking String");
            if (err) {
                reject(err);
            }
            if (data.indexOf(word) >= 0) {
                resolve(filePath);
            }
        })
    })
}
Sign up to request clarification or add additional context in comments.

5 Comments

what about the line the call getFiles recursivly "return getFiles(path + '\\' + currentFile, ext, word);", is this fine?
need to use resolve like this resolve(getFiles(path + '\\' + currentFile, ext, word))
Im reading about promise now, I added a console logs to the file "console.log("Start");" inside "function getFiles(path, ext, word) {" but the output is "start [] end start start start start", Im checking how to fix it.
It's hard to tell what's happening as i not sure where u put it, the minute you use promise it'll make sure it waits for the process to execute before sending the response to resolve or reject within the promise block.
And you are using recursive code getFiles( is calling getFiles( again, it hard tell unless u debug your code to understand when the log happened. try some ide like vscode to debug

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.