Basavaraj V
2 min readJun 17, 2020

--

Creating a zip file dynamically on requested by the client in NodeJS/Loopback

I had been working on a requirement to provide a sample CSV file for the import of memberships for organizations. The challenge was to make the users aware of how each field needs to be defined since some of the fields were required, some were optional, some supported only a certain set of strings.

We added these instructions to the start of the CSV but then users were confused about what rows to keep in the CSV before the import.

We then thought of providing the sample CSV file and the instructions as two different files respectively zipped together when the user downloads. But since our sample CSV file was autogenerated based on the passed parameters we couldn't keep our files n the filesystem zipped and then sent. The option left with us was to stream the zip file that we would build on the fly. That's when we came across the “archiver” npm package.

There have been various examples of how to use the “archiver” node module with express. but something I could hardly find was the one with loopback (loopback.io). Most of the examples out there didn't work for me and always returned a “Failed — No file” error on triggering a download. Hence after a lot of trials and errors, something worked.

The below code snippet is pretty much straight forward on how to achieve archiving at a loopback based server and download from the browsers.

//install archieve
npm install archiver --save
//Inject the response object into the Constructor of your controller
//This is required if you are using loopback.io or your express.js controller already has a response object
@inject(RestBindings.Http.RESPONSE)
protected response: Response,
//To start archiving
var archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
});
this.response.attachment("download.zip")
var bufferForFile1 = Buffer.from("Content of file 1");
var bufferForFile2 = Buffer.from("Content of file 2");
//response need to be added to the pipe before your add your dynamic content.
archive.pipe(self.response)
archive.append(bufferForFile1, { name: 'file1.txt' });
archive.append(bufferForFile2, { name: 'file2.txt' });
archive.finalize()
//The critical part that helped is returning the response.
return this.response;

I hope the above code helps someone who is struggling to create a dynamic archive file in nodejs/express framework.

If the above content helped you please leave a 👏. It would encourage me to write more such articles.

--

--

Basavaraj V

Tech Enthusiast | Programmer | Architect | Likes to Travel | Interests in Technology, History, Languages, Science