0

I would like to know to read the files and search for keyword sample in nodejs.

If keyword found, display the path

const allfiles = [
  'C:\\Users\\public',
  'C:\\Users\\public\\images',
  'C:\\Users\\public\\javascripts\\index1.js',
  'C:\\Users\\public\\javascripts\\index2.js'
]


const readFile = (path, opts = 'utf8') =>
  new Promise((resolve, reject) => {
   try{
      let result=[];
      fs.readFile(path, opts, (err, data) => {
        if (err) reject(err)
        else {
          if(data.indexOf("sample")>=0){
             result.push(data);
             resolve(result);
          }
        }
      })
    }
    catch (e) {
      console.log("e", e);
     }
  })

  const run = async () => {
    allfiles.forEach(e=>{
      const s = await readFile(e);
      console.log(s);
    })
  }
run();

Expected Output
[
  'C:\\Users\\public\\javascripts\\index1.js',
  'C:\\Users\\public\\javascripts\\index2.js'
]

ved
  • 167
  • 9

1 Answers1

2

Some tips:

  1. What happens when "sample" isn't found in readFile?
  2. You're currently pushing the data into result instead of the path.
  3. Think about what you're trying to accomplish with readFile. To me, what you want to do is see if that file has the word "sample", and return true if so and if not return false. So I'd name the function checkIfFileHasSample and have it return a boolean. Then in your run function, in the forEach you have the path, so that is where I'd add the path to a list of results.
  4. Maybe you already realized this, but run is never actually called in your code sample. Ie. run() doesn't happen.

Solution:

You had some syntax errors and a tricky gotcha with async-await with run. For the syntax errors, it'll come with experience, but I'd also recommend using ESLint to help you catch them, as well as making sure your code is always properly indented.

const fs = require("fs");
const allfiles = [
  "C:\\Users\\public",
  "C:\\Users\\public\\images",
  "C:\\Users\\public\\javascripts\\index1.js",
  "C:\\Users\\public\\javascripts\\index2.js",
];

const checkIfFileHasSample = (path, opts = "utf8") =>
  new Promise((resolve, reject) => {
    fs.readFile(path, opts, (err, data) => {
      if (err) {
        reject(err);
      } else {
        if (data.includes("sample")) {
          resolve(true);
        } else {
          resolve(false);
        }
      }
    });
  });

const run = async () => {
  const results = [];

  for (let i = 0; i < allFiles.length; i++) {
    try {
      const file = allFiles[i];
      const hasSample = await checkIfFileHasSample(file);

      if (hasSample) {
        results.push(file);
      }
    } catch (e) {
      console.log(e);
    }
  }

  console.log(results);
};
run();
Adam Zerner
  • 17,797
  • 15
  • 90
  • 156
  • thanks a lot for helping, but getting error `UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: EISDIR: illegal operation on a directory, ` – ved Feb 22 '21 at 01:09
  • 1
    Whoops, I forgot the `try-catch`. I updated my code to include it. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#promise_rejection for why it's needed. That won't solve your root problem though. `illegal operation on a directory` sounds like there's a problem with `fs.readFile`. It worked for me, so it's probably that your file paths are wrong. – Adam Zerner Feb 22 '21 at 02:35