1

I'm trying to figure out why the front end of my app is not receiving the file that Express seems to think it's sending.

The intended behavior for the app is for the user to click a "generate PDF" button on the angular-powered form on the front end, then have the backend generate the PDF and send it to the user once it has finished being created. I can confirm that the PDFs are successfully generating, and everything else is working as intended, but res.sendFile seems to be failing to trigger a file download on the front end side of things.

Here's the code I'm using to trigger the download:

var labelStream = fs.createWriteStream('labels/' + transaction.object_id + '.pdf');

request(transaction.label_url).pipe(rawLabelStream);
rawLabelStream.on('finish', function () {
    var doc = new PDFDocument;
    doc.text(req.body.sku, 115, 315, {"width": "150", "align": "center"});
    doc.image('rawlabelpng/' + transaction.object_id + '.png', 325, 75, {"width": "250"});
    doc.moveDown();
    doc.text (req.body.note, 100, 645, {"align": "center"});
    doc.pipe(labelStream);
    doc.end();

    labelStream.on('finish', function () {
        console.log("PDF has been generated!");
        res.sendFile('/absPath/to/files/' + transaction.object_id + '.pdf', {"headers":{
            "content-type": "application/pdf",
            "content-disposition": "attachment"
        }}, function (err){
            if (err) {
                console.log(err);
                res.status(err.status).end();
            }
            else {
                console.log('Sent: ' + transaction.object_id + '.pdf');
            }
    });
});

When I test the code above, I get the "Sent: xxxxxxxxx.pdf" log in my console, which suggests there's no explicit error getting tripped. Express seems to think the file is getting sent successfully, but the download never triggers in the browser. Sadly, running nodemon with the DEBUG=express:* flag didn't provide me with any extra information about what res.sendFile is doing.

Earlier, I was running into the TypeError about absolute files, so I entered the absolute path to the file starting from the server's root directory. Since that change, I haven't seen any errors from Express but it still doesn't seem to be working right. I'm hoping that's the correct way to configure the absolute path, and I'm thinking Express would send an ENOENT error if the path was incorrect and didn't actually lead to a file... right?

Has anyone run into something like this before?

If it helps, I've tried replacing res.sendFile with res.download with no change in behavior.

wingmatt
  • 72
  • 2
  • 7
  • http://stackoverflow.com/questions/20508788/do-i-need-content-type-application-octet-stream-for-file-download – Ya Zhuang Aug 18 '16 at 05:24
  • 1
    Did u checked filepermission and set proper header? – RIYAJ KHAN Aug 18 '16 at 05:27
  • @bitsMix I just tried explicitly setting the content-type and content-disposition headers in the response, but sadly there was no change in behavior. – wingmatt Aug 18 '16 at 05:48
  • @R.J file permissions look good to me (correct user, with read permissions), and explicitly setting content headers didn't change the app's behavior. – wingmatt Aug 18 '16 at 05:50
  • 1
    Are you expecting the download to occur over a XHR request, by any chance? Is so, you'll either need iframes or this technique on your front-end: http://stackoverflow.com/questions/17696516/download-binary-files-with-javascript – Mihai Potra Aug 18 '16 at 22:22
  • @MihaiPotra Thanks for pointing that out! After doing some more research on Angular's $http method, I think this may be the underlying issue - [$http uses XHR](https://docs.angularjs.org/api/ng/service/$http), which makes a straight-up file download like I'm attempting impossible as you said. I'll check out the solutions you linked in more detail and try to answer this question myself once I get it working. – wingmatt Aug 19 '16 at 18:32

0 Answers0