NodeJs – Get last modified file in sub directories of directory

Issue

I have the following code to list all folders within a directory, and it maps each folder’s name and date created. I’m struggling to get the last modified file within the sub directories of the folders.

const fs = require('fs')
const glob = require("glob")

const getDirectories = (source, callback) => {

    const getDirectories = function (src, callback) {
        glob(src + '/*/*/*', callback)
    }

    fs.readdir(source, { withFileTypes: true }, (err, files) => {
        if (err) {
            callback(err)
        } 
        else {
            callback(
                files
                .filter(dirent => dirent.isDirectory())
                .map(name => ({
                    name: name.name,
                    created: fs.statSync(`${source}\\${name.name}`).birthtime.toLocaleString(navigator.language, {
                            day: '2-digit',
                            month: 'short',
                            year: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit'
                        }
                    ),
                    modified: getDirectories(`${source}\\${name.name}`, function (err, res) {
                        res = res.map(file => ({ file, mtime: fs.lstatSync(file).mtime }))
                        .sort((a, b) => b.mtime - a.mtime)
                        return res.length ? res[0] : ''
                    })
                }))
                .sort(function (a, b) {
                    if ($sort == 1) {
                        if (a.name < b.name) return -1;
                        if (a.name > b.name) return 1; 
                        return 0;
                    }
                    else if ($sort == 2) {
                        if (a.name > b.name) return -1;
                        if (a.name < b.name) return 1; 
                        return 0;
                    }
                    else if ($sort == 3) {
                        if (a.created < b.created) return -1;
                        if (a.created > b.created) return 1; 
                        return 0;
                    }
                    else if ($sort == 4) {
                        if (a.created > b.created) return -1;
                        if (a.created < b.created) return 1; 
                        return 0;
                    }
                    else if ($sort == 5) {
                        if (a.modified < b.modified) return -1;
                        if (a.modified > b.modified) return 1; 
                        return 0;
                    }
                    else if ($sort == 6) {
                        if (a.modified > b.modified) return -1;
                        if (a.modified < b.modified) return 1; 
                        return 0;
                    }
                })
            )
        }
    })
}

My problem is with the follwing snippet:

modified: getDirectories(`${source}\\${name.name}`, function (err, res) {
                    res = res.map(file => ({ file, mtime: fs.lstatSync(file).mtime }))
                    .sort((a, b) => b.mtime - a.mtime)
                    return res.length ? res[0] : ''
                })

I’m struggling to get a return value to set the modified object.
If I do console.log(res) I can see that I get the expected result

I’m listing all the folders in HTML with the name, created and modified properties.

An example of the directories:

Working Dir
├──Work Space1
   └──Category1
      └──Location_a
         └── *.file_a1
         └── *.file_a2
         └── *.file_a3
      └──Location_b
         └── *.file_b1
         └── *.file_b2
         └── *.file_b3
   └──Category2
      └──Location_a
         └── *.file_a1
         └── *.file_a2
         └── *.file_a3
      └──Location_b
         └── *.file_b1
         └── *.file_b2
         └── *.file_b3
├──Work Space2
   └──Category1
      └──Location_a
         └── *.file_a1
         └── *.file_a2
         └── *.file_a3
      └──Location_b
         └── *.file_b1
         └── *.file_b2
         └── *.file_b3
   └──Category2
      └──Location_a
         └── *.file_a1
         └── *.file_a2
         └── *.file_a3
      └──Location_b
         └── *.file_b1
         └── *.file_b2
         └── *.file_b3

I need to get the last modified file of each file within each Work Space regardless of the sub folders

And example of the HTML output:

enter image description here

Solution

try with recursive function, add stats you need, then you can sort the results.

check the code (directory path is included so you could work out hierarchy if needed (credits for reading files solution: Smally’s answer)):

const getDirectories = (source) => {

    const files = [];

    function getFiles(dir) {

        fs.readdirSync(dir).map(file => {

            const absolutePath = path.join(dir, file);

            const stats = fs.statSync(absolutePath);

            if (fs.statSync(absolutePath).isDirectory()) {

                return getFiles(absolutePath);

            } else {
                const modified = {
                    name: file,
                    dir: dir,
                    created: stats.birthtime.toLocaleString(navigator.language),
                    modified: stats.mtime
                };
                return files.push(modified);
            }
        });
    }

    getFiles(source);
    return files;
}


const files = getDirectories(somePath);

console.log('\ngot files:', files.length);

// sort...
const lastModified = files.sort((a, b) => b.modified - a.modified);

console.log('\nlast modified:\n', lastModified[0]);

Answered By – traynor

Answer Checked By – David Marino (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.