Sunday, 12 March 2017

Trigger CSV file download with Angular

This question has been asked a fair bit before, but none of the solutions I've seen seem to work, potentially because of the way I stream the file back to the browser. The CSV I ultimately want is in a private S3 bucket and because of security middleware, I have to get it via a NodeJS endpoint. The code for the API is below.

exports.download = function(req, res) {

    var recording = req.vsRecording,
        s3 = new AWS.S3();

    if(recording.data_uri){
        try{
            res.set('Content-Type', 'application/octet-stream');
            var fileStream = s3.getObject({Bucket: 'processing-dispatched', Key: recording._id + '/aggregated.csv'}).createReadStream();
            fileStream.pipe(res);
        }
        catch(err){
            res.status(500).json({error: err});
        }
    }
    else {
        res.status(500).json({error: 'Recording does not have a report file.'});
    }
};

This works perfectly and I can get the content of the file back to the browser. When it goes wrong is trying to get that content into be opened as a file download. Is there a special way to handle downloading streams?

The closest I've got is this code on the client, which sometimes seems to work on localhost if I turn my adblocker off - but does not work in production.

$scope.download = function(){
    Report.download($state.params.recordingId).then(function(data){
    var csvContent = "data:text/csv;charset=utf-8," + data.toString();
    var encodedUri = encodeURI(csvContent);
    window.open(encodedUri);
});

Report.download is just an angular service wrapper around my Node endpoint, it returns a promise and resolves the content of the file in the data variable.



via Mark

No comments:

Post a Comment