I am trying to return the file in a directory with the earliest modification date. This approach seems to be failing in the createFileDateMap function. I want to reduce over an array of file paths and create an object with the filename and mod-dates. The getModDate function is an asynchronous fs.lstat call. I can't seem to set acc of my reducer to the values from within a .then() block. I'm not sure how to achieve reducing when the values depend on asynchronous call
var _ = require('lodash'),
fs = require('fs'),
path = require('path'),
Q = require('q');
function checkDir(dir) {
// Check if given path is valid directory
var deferred = Q.defer();
fs.lstat(dir, deferred.makeNodeResolver());
return deferred.promise.invoke('isDirectory');
}
function getFiles(dir) {
// Get all files within a directory
var deferred = Q.defer();
fs.readdir(dir, deferred.makeNodeResolver());
return deferred.promise;
}
function makeFullPathFileArr(dir, files) {
// Return array of full paths
return _.map(files, function(file) {
return path.join(dir, file);
});
}
function getModDate(file) {
// Return modification date of file
var deferred = Q.defer();
fs.stat(file, deferred.makeNodeResolver());
return deferred.promise.get('mtime');
}
function createFileDateMap(filesArr) {
// Return an obj of file paths and modification dates as Date objects
// {{ file1: Date, file2: Date }}
var fileDateMap = _.reduce(filesArr, function(acc, file) {
getModDate(file)
.then(function(modDate) {
acc[file] = moment(modDate);
});
return acc;
}, {});
return fileDateMap;
}
function getMinDateFile(mapObj) {
// return the file name which has the earliest modification date
var dates = _.transform(mapObj, function(result, date, key) {
result[key] = new Date(date);
});
var minDate = new Date(Math.min.apply(null, _.values(dates)));
var invertedMapObj = _.invert(mapObj);
return invertedMapObj[minDate];
}
var dir = '../reports';
checkDir(dir)
.then(function(exist) {
if(exist) {
getFiles(dir)
.then(function(fileNames) {
return makeFullPathFileArr(dir, fileNames);
})
.then(function(fullpathsArr) {
return createFileDateMap(fullpathsArr);
})
.then(function(fileAndDatesObj) {
console.log(getMinDateFile(fileAndDatesObj));
});
}
})
.catch(function(err) {
console.log(err);
});