Mark
Mark

Reputation: 858

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.

Upvotes: 1

Views: 1028

Answers (1)

nmanikiran
nmanikiran

Reputation: 3148

reason might be the browser blocking the new window. Allow all sites to show pop-ups in browser setting.

you can try thing in different ways create a file in node with fs and return url to the Front-end

or

you can Try the following code

$scope.download = function() {
Report.download($state.params.recordingId).then(function(data) {
    var csvContent = "data:text/csv;charset=utf-8," + data.toString();
    var a = document.createElement('a');
    a.href = "data:application/csv;charset=utf-8," + csvContent;
    a.setAttribute('download', "abc.csv");
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
 });
}

Upvotes: 1

Related Questions