1

I'm trying to read through a directory structure and sub-directories to find a file with a name that matches a set of criteria. I'm using a recursive function to walk through each item in a directory. If its a file and matches the criteria, return the file path, otherwise, move on to the next item.

I can log the match when I find it, but getting UNDEFINED when trying to return from the function.

Many SO posts like here and here indicate I need to add a return statement to the recursion call but I can't seem to get it right.

How can I return from this function?

function checkForProjectTrackFile(projfolder, projname) {

  fs.readdirSync(projfolder).forEach(projfile => {

    if (fs.statSync(path.join(projfolder, projfile)).isDirectory()) {

      //if a directory, call function again
      return checkForProjectTrackFile(path.join(projfolder, projfile), projname)
      
    } else {
        
        if (isProjectTrackMatch(projfile, projname)) {
          
          console.log("Match Found", path.join(projfolder, projfile))
          
          //match criteria met, return the file path  => UNDEFINED

          return (path.join(projfolder, projfile))
        }
    }
 })
}

1 Answers1

0

Each time through checkForProjectTrackFile() you need to return a value indicating you found the result (in this case a string) or a value indicating none was found (I chose null):

function checkForProjectTrackFile(projfolder, projname) {
  let r = null; // assume

  fs.readdirSync(projfolder).forEach(projfile => {

    if (fs.statSync(path.join(projfolder, projfile)).isDirectory()) {

      //if a directory, call function again
      r = checkForProjectTrackFile(path.join(projfolder, projfile), projname)
      if ( r !== null ) {
         break; // Found a match, so unwind and get out
         // Note: return r would also work here
      } // no need for 'else' since we want to keep looping to check the rest of the projfile values at this level!
      
    } else {
      if (isProjectTrackMatch(projfile, projname)) {
          
        console.log("Match Found", path.join(projfolder, projfile))
          
        //match criteria met, return the file path  => UNDEFINED

        r = (path.join(projfolder, projfile));

        break; // We found a match, so stop processing directory entries
      }
    }
  })

  return r; // Return what we found (whether null or otherwise)
}
kmoser
  • 8,780
  • 3
  • 24
  • 40
  • Thanks, @kmoser. Suggested code returned "null" in all conditions, but moving "r = checkForProjectTrackFile()...." directly below the "if (r ! == null)" block returns null or match as desired. Appreciate the comments too, helpful in understanding. Also, [using **break** caused some syntax errors](https://stackoverflow.com/questions/47017571/cannot-break-for-loop-unsyntactic-break), but using **return** did the trick. – bcarp121177 Aug 12 '20 at 16:55
  • @bcarp121177 Right, I forgot you were using `forEach()` which doesn't support `break`. Glad you got it working! – kmoser Aug 12 '20 at 20:24