Node.js, Directory-tree, and native JS classes

I tried posting this issue I was facing last night but didn’t get around to it. This morning I solved it, but I wanted to share because it was a fun problem to deal with. I am still pretty novice with JavaScript so I learned a lot through this exercise.

I have been taking a Udemy Course and was building a project and ended up downloading about 45 images, put them in a relative folder, and one by one pasted them into an array. I knew at that point I messed up, but I let it simmer a few days.

I found out about the Node Package called directory tree and thought I would give it a go. I skipped reading much of the documentation and just took to trying things out. If you aren’t aware of this package, it will give your Node.js app access to a folder of your choosing by calling it and passing in the relative path.

I stumbled through it but after realizing it was possible to create maps inside of filters inside of functions and that IIFEs will jump out of your code and run in the very beginning and all sorts of crazy mishaps and adventures, I came up with a working solution. It wasn’t the best though and I was well aware of this. At this point is when I was ready to throw my hands up and ask for some suggestions. The problem with this version is that I was repeating myself and had to write the same functions inside of maps to return the children of folders. It would only go as deep into the folder as I would hard code it. I spend the next day working on a better solution, but here is what I was working with early on.

const dirTree = require("directory-tree");
const folders = data.filter(folder => folder.children).map(file => {
       if (file.extension)
       return {
        url: file.path.replace(/\\/g,'/'),
        filename: `${file.extension ? file.extension.slice(1) : file.extension}`
       }
       else if (!file.extension) 
           return {
            name: file.name,
            files: file.children.map(subfolder => {
                if (subfolder.extension)
                    return {
                        url: subfolder.path.replace(/\\/g,'/'),
                        filename: subfolder.extension.slice(1)
                    }
                    else return {
                        name: subfolder.name,
                        files: subfolder.children.map(dubfolder => {
                            if (dubfolder.extension)
                            return {
                                url: dubfolder.path.replace(/\\/g,'/'),
                                filename: dubfolder.extension.slice(1)
                            }
                            else return {
                                name: dubfolder.name,
                                files: dubfolder.children.map(layerfour => {
                                    if (layerfour.extension)
                                    return {
                                        url: layerfour.path.replace(/\\/g, '/'),
                                        filename: layerfour.extension.slice(1)
                                    } 
                                    else return {
                                        name: layerfour.name,
                                        files: layerfour.map(layerfive => {
                                            return {
                                                url: layerfive.path.replace(/\\/g, '/'),
                                                filename: layerfive.extension.slice(1)
                                            }
                                        })
                                    }
                                })
                            }
                        })
                    }
            })
           }
   })

It’s horrendous, I know, but I wasn’t striving for pretty and I knew I was on the wrong path but I wanted to at the very least get it to go as deep as I could before it became the above code. I had to write so many if and else statements to prevent errors from occurring. After this and about a dozen more scratched prototypes, I finally stepped back and remembered that JS offers classes and figured I should utilize this model. It took probably a hundred more attempts. I was seeing things called circular loops and still don’t know much about them but once I started seeing them appear, I started making more progress. Finally as I was about to call it due to thinking I was insane for trying this so many times…Lowe and behold

const dirTree = require("directory-tree");
class Root {
    constructor(dir){
       const root = dirTree(dir)
       this.url = root.path.replace(/\\/g,'/')
       this.files = new Folder(this.url)
    }
}
class File {
    constructor(file){
       const root = dirTree(file)
       this.url = file
       this.name = root.name
       this.files = this.collapseFolder(this.url)
       return this
    }
    collapseFolder(url){
        const root = dirTree(url);
        const files = [];
        if (root.children.map)
        root.children.map(child => {
            if (child.extension) {
                const url = child.path.replace(/\\/g, '/')
                const filename = child.extension.slice(1)
                files.push({ url, filename })
             } else files.push(new File(child.path.replace(/\\/g,'/')))
        })
        return files
}
}

class Folder extends Array{
    constructor(files) {
    const root = dirTree(files)
    return root.children.map(child => {
        const url = child.path.replace(/\\/g,'/')
        return new File(url)
    })
  }   
}
const seeds = new Root('./public/assets/images/seeds/');
console.log(seeds.files[3].files[1].files[0].files);
/*
console.log(seeds.files[3].files[1].files[0]) returns File {
  url: 'public/assets/images/seeds/test/fa/faws',
  name: 'faws',
  files: [
    {
      url: 'public/assets/images/seeds/test/fa/faws/4K-Cat-Wallpaper-For-Desktop1.jpg',
      filename: 'jpg'
    }
  ]
}
seeds.files[3].files[1].files[0].files returns [
  {
    url: 'public/assets/images/seeds/test/fa/faws/4K-Cat-Wallpaper-For-Desktop1.jpg',
    filename: 'jpg'
  }
*/

Much prettier, much less repetitive, I am very much more proud of this than my first attempt.

With that though, I want to thank you for reading this post, and request that you provide any sort of feedback or suggestion for the future =) Thank you in advance and happy coding!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.