简体   繁体   中英

Recursively load files from directory and subdirectories with require-all

I have json files within a directory and subdirectory that I am wanting to match with specific criteria, however I am unaware as how to work with the subdirectories.

I am using require-all to find the json files:

const reqAll = require('require-all')({
  dirname: __dirname + '/resource',
  filter: /(.+)\.json$/,
  recursive: true
});

My file tree is as such:

MyDir
- file1.json
- SubDir
-- file2.json

Printing reqAll will output:

{ 
  file1: { 
    path: /first,
    body: ...some body
  },
  SubDir: { 
    file2: { 
      path: /second,
      body: ...some body
    } 
  } 
}

I was initially using the following filter to weed out my data, as I was originally not using subdirectories, but now it makes sense to.

let source = Object.values(reqAll).filter(r => {
    return r.path === req.url;
}

where req.url is the url of the http request I am sending in. ie: localhost:8080/first , so that this will match with the file1 file I have in my directory.

The problem is that when I submit localhost:8080/second , I do not get a response because I cannot match to file2 as this is within a subdir. Also sending localhost:8080/SubDir/file2 does not work.

Is there a way in which I can get this to work?

In a comment you've written:

So, I will perform a HTTP GET on, localhost:8080/first and it should return me the body of the file1 object. This does in fact work for this endpoint. However, it is when I perform a HTTP GET on localhost:8080/second that I cannot get the body back.

To do that, you'll need a recursive search for the entry with that path , something along these lines (see comments):

 const repAll = { file1: { path: "/first" }, SubDir: { file2: { path: "/second" }, SubSubDir: { file3: { path: "/third" } } } }; const req = {}; function findEntry(data, path) { for (const value of Object.values(data)) { // Is this a leaf node or a container? if (value.path) { // Leaf, return it if it's a match if (value.path === path) { return value; } } else { // Container, look inside it recursively const entry = findEntry(value, path); if (entry) { return entry; } } } return undefined; // Just to be explicit } for (const url of ["/first", "/second", "/third", "fourth"]) { req.url = url; console.log(req.url + ":", findEntry(repAll, req.url)); } 
 .as-console-wrapper { max-height: 100% !important; } 

I added a second subdirectory to ensure the recursion keeps working, and an example of what you get back if you don't find a matching path.

You could, of course, build a map by processing repAll once up front and then reuse the map, which would be faster than this linear search:

 const repAll = { file1: { path: "/first" }, SubDir: { file2: { path: "/second" }, SubSubDir: { file3: { path: "/third" } } } }; const byPath = new Map(); function indexEntries(map, data) { for (const value of Object.values(data)) { if (value) { // Leaf or container? if (value.path) { map.set(value.path, value); } else { indexEntries(map, value); } } } } indexEntries(byPath, repAll); const req = {}; for (const url of ["/first", "/second", "/third", "fourth"]) { req.url = url; console.log(req.url + ":", byPath.get(req.url)); } 
 .as-console-wrapper { max-height: 100% !important; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM