I'm using loopback-component-storage with the filesystem provider to upload photos. It works great. But now I have a request to 'export/download' photos to a zip archive.
I've put together some code to add another method, downloadContainer()
to Container
from the file-storage example. It uses the Archiver
module, everything seems to work fine, but the browser crashes after I call zip.finalize()
I'm expecting to get a save file
dialog box instead...
Here is my code so far:
Container.downloadContainer = function(container, files, res, cb) {
var DELIM, _appendFile, _finalize, _oneComplete, _remaining, filenames, storageService, zip;
zip = Archiver('zip');
zip.pipe(res);
storageService = this;
_remaining = {};
_appendFile = function(zip, container, filename) {
var reader;
console.log('appendFile=' + filename);
reader = storageService.downloadStream(container, filename, function(stream) {
return console.log('storageService.downloadStream() resp=', _.keys(stream));
});
zip.append(reader, {
name: filename
});
};
zip.on('error', function(err) {
console.log('zip entry error', err);
res.status(500).send({
error: err.message
});
});
zip.on('entry', function(o) {
return _oneComplete(o.name);
});
_oneComplete = function(filename) {
delete _remaining[filename];
console.log('_oneComplete(): ', {
remaining: _.keys(_remaining),
size: zip.pointer()
});
if (_.isEmpty(_remaining)) {
_finalize();
}
};
_finalize = function() {
console.log('calling zip.finalize() ...');
res.on('close', function() {
console.log('response closed');
res.attachment(container + '.zip');
return res.status(200).send('OK').end();
});
zip.finalize();
};
if (files === 'all' || _.isEmpty(files)) {
console.log('files=', files);
storageService.getFiles(container, function(err, ssFiles) {
_remaining = _.object(_.pluck(ssFiles, 'name'));
console.log('filenames=', _.keys(_remaining));
return ssFiles.forEach(function(file) {
_appendFile(zip, container, file.name);
});
});
}
}
and here is what I see in the console
// log
files= all
filenames= [ 'IMG_0799.PNG', 'IMG_0800.PNG', 'IMG_0801.PNG', 'IMG_0804.PNG' ]
appendFile=IMG_0799.PNG
appendFile=IMG_0800.PNG
appendFile=IMG_0801.PNG
appendFile=IMG_0804.PNG
_oneComplete(): { remaining: [ 'IMG_0800.PNG', 'IMG_0801.PNG', 'IMG_0804.PNG' ],
size: 336110 }
_oneComplete(): { remaining: [ 'IMG_0801.PNG', 'IMG_0804.PNG' ], size: 460875 }
_oneComplete(): { remaining: [ 'IMG_0804.PNG' ], size: 1506464 }
_oneComplete(): { remaining: [], size: 1577608 }
calling zip.finalize() ...
// then browser crash