0

I cant manage to return a zip file in http response from nodejs with express. I'm using ArchiverJS and azure-function-express. I've been trying to figure this out for a day now and I cant get it to work..

My code:

const createHandler = require("azure-function-express").createHandler;
const express = require("express");

// Create express app as usual
const app = express();


app.get("/api/download", (req, res) => {

    var Archiver = require('archiver');

    // Tell the browser that this is a zip file.
    res.writeHead(200, {
        'Content-Type': 'application/zip',
        'Content-disposition': 'attachment; filename=myFile.zip'
    });

    var zip = Archiver('zip');

    // Send the file to the page output.
    zip.pipe(res); // <--- GENERATES TypeError: Cannot read property 'length' of null 

    // Create zip with some files. Two dynamic, one static. Put #2 in a sub folder.
    zip.append('Some text to go in file 1.', { name: '1.txt' })
        .append('Some text to go in file 2. I go in a folder!', { name: 'somefolder/2.txt' })
        .file('staticFiles/3.txt', { name: '3.txt' })
        .finalize();

});
// Binds the express app to an Azure Function handler
module.exports = createHandler(app);

I dont have any experience about pipes but I think it's where it fails..

This will generate following error and I bet that it has to do with the "zip.pipe(res)". Maybe someone can explain what i'm doing wrong?

[error] Worker 50fea52b-2a26-4eee-bf1a-5956a3bda16f uncaught exception (learn more: https://go.microsoft.com/fwlink/?linkid=2097909 ): TypeError: Cannot read property 'length' of null  
   at ServerResponse._send (_http_outgoing.js:231:33 undefined)  
   at write_ .write_ (_http_outgoing.js:625:15 undefined)  
   at ServerResponse.write (_http_outgoing.js:567:10 undefined)  
   at Archiver.ondata (C:\Users\KENUBBE\Desktop\smarthelmet-ml\node_modules\readable-stream\lib\_stream_readable.js:681:20 undefined)  
   at Archiver.emit (events.js:198:13 undefined)  
   at addChunk .addChunk (C:\Users\KENUBBE\Desktop\smarthelmet-ml\node_modules\readable-stream\lib\_stream_readable.js:298:12 undefined)  
   at readableAddChunk .readableAddChunk (C:\Users\KENUBBE\Desktop\smarthelmet-ml\node_modules\readable-stream\lib\_stream_readable.js:280:11 undefined)  
   at Archiver.Readable.push (C:\Users\KENUBBE\Desktop\smarthelmet-ml\node_modules\readable-stream\lib\_stream_readable.js:241:10 undefined)  
   at Archiver.Transform.push (C:\Users\KENUBBE\Desktop\smarthelmet-ml\node_modules\readable-stream\lib\_stream_transform.js:139:32 undefined)  
   at Archiver.afterTransform (C:\Users\KENUBBE\Desktop\smarthelmet-ml\node_modules\readable-stream\lib\_stream_transform.js:88:10 undefined)
KENUBBE
  • 79
  • 1
  • 5
  • 12
  • To solve this, try to isolate the error. First, make a program that writes your archive to the disk without express. – CoderFF Apr 30 '20 at 04:44
  • Also, you posted the stack trace in a way I can't read it – CoderFF Apr 30 '20 at 04:45
  • Sry, I updated the stack trace... zip.pipe(res); // <--- GENERATES TypeError: Cannot read property 'length' of null – KENUBBE Apr 30 '20 at 15:28
  • fs.createReadStream(`${__dirname}/measurements_Person-${person}_OrderNumber-${orderNumber}.zip`).pipe(res); <--- generates the same error when trying to pipe archive on my disk with the http response. – KENUBBE Apr 30 '20 at 15:54

1 Answers1

2

I've made a minimal working example and it's pretty much the same as yours. It works for me. It uses:

node@10.16.0

express@4.17.1

archiver@4.0.1

const express = require("express");
// Create express app as usual
const app     = express();
const http    = require('http');
const server  = http.createServer(app);


app.get("/api/download", (req, res) => {

    var Archiver = require('archiver');

    // Tell the browser that this is a zip file.
    res.writeHead(200, {
        'Content-Type': 'application/zip',
        'Content-disposition': 'attachment; filename=myFile.zip'
    });

    var zip = Archiver('zip');

    // Send the file to the page output.
    zip.pipe(res); // <--- GENERATES TypeError: Cannot read property 'length' of null 

    // Create zip with some files. Two dynamic, one static. Put #2 in a sub folder.
    zip.append('Some text to go in file 1.', { name: '1.txt' })
        .append('Some text to go in file 2. I go in a folder!', { name: 'somefolder/2.txt' })
        .file('staticFiles/3.txt', { name: '3.txt' })
        .finalize();

});

server.listen(7070);
CoderFF
  • 190
  • 1
  • 10
  • Hmm ok, so everything works because of server.listen(7070).. But why? :O – KENUBBE Apr 30 '20 at 16:18
  • Does this work on your local machine? I just thrown out the 'azure-function-express' cause i'm not used to it – CoderFF Apr 30 '20 at 17:04
  • also, there may be difference in modules versions, this is why I've posted versions that I use – CoderFF Apr 30 '20 at 17:05
  • This is working on my local machine, now I have to try it in azure function also.. azure-function-express is a library to use node.js with express in azure functions instead of native javascript – KENUBBE Apr 30 '20 at 17:20