Trigger CSV file download with Angular - angularjs

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.

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);
});
}

Related

How to save SURVEY PDF on the disk

I want to save somes PDF created with 'survey-pdf' on my disk.
Actually, i can send the PDF but i can't save it on my disk.
My final code :
return surveyPDF.save(filename);
Someone can help me ?
Thank you
Can you try
await surveyPDF.save(filename)
?
.save seems to be an asynchronous function that downloads the PDF file.
From the docs
Call save method of surveyPDF object to download file in browser. This is asynchronous method
#2 If the first method doesn't work, you can try this
function savePdfAsString() {
const surveyPDF = new SurveyPDF.SurveyPDF(json);
surveyPDF.data = survey.data;
surveyPDF
.raw("dataurlstring")
.then(function (text) {
//var file = new Blob([text], {type: "application/pdf"});
var a = document.createElement("a");
//a.href = URL.createObjectURL(file);
a.href = text;
a.download = "surveyAsString.pdf";
//document
// .body
// .appendChild(a);
a.click();
});
}
Here you are using the .raw function to transform the PDF into a dataurlstring and then downloading that. Here's the docs for this
*Not tested

How to automatically download a xlsx file(in angularjs 1) sent by server

The HTTP response for a POST request that I am getting from server side is a xlsx file.How do I download the file in angularjs 1?
Note: res.download() won't work here,since its a POST request that I am making,and res.download() works only for GET request
The following shall work :
$http.post("url_here", post_data_to_send, {responseType: 'arraybuffer'})
.success(function (data,status,headers) {
var blob = new Blob([data]);
var objectUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
a.style = "display:none";
a.href = objectUrl;
a.download = headers().filename;
a.click();
console.log("Report downloaded");
}).error(function (err) {
console.log(err);
});
You can do it directly on Client Side, you may have some cross-browser compatibility issues (the best way is always to provide a download stream via server, for large files for example).
// this example uses a JSON String
// but you can do it with any valid blob argument
const fileContent = [JSON.stringify(
['something', 'to', 'download'], null, 2
)];
const downloader = document.createElement('a');
// set the filename here
downloader.download = 'filename.json';
const blob = new Blob(fileContent, {type: 'text/plain'});
downloader.href = window.URL.createObjectURL(blob);
// trigger the download
downloader.click();
In my opinion, a redirect to the downloadable resource could be the best choice.

Is there a way to dump a thousand images somewhere and extract them using REST Api?

Here is the thing:-
I have over a thousand images saved locally in my mac. I have a landing page that mocks an ecommerce deal site. It would be tedious to have to manually type in the src url in the img tag for a thousand pictures. Thus, i thought i could somehow have this images dumped in a cloud storage or something and use REST api get method to extract these images in a response.data. Then assign it to a $scope variable and use ng-repeat to bind the images in my landing page view. Is this possible? If not, what are the alternatives? SQL database?
Appreciate your help. P.S. I am totally a beginner at web development.
Install node.js. It's Javascript for a server which should make it pretty easy since you already know Javascript.
On a Mac, you can install node like this:
brew install node
Use this node.js code (credit to codepedia.com, tweaked a little by me):
//include http, fs and url module
var http = require('http'),
fs = require('fs'),
path = require('path'),
url = require('url');
imageDir = './images/';
//create http server listening on port 3333
http.createServer(function (req, res) {
//use the url to parse the requested url and get the image name
var query = url.parse(req.url,true).query;
pic = query.image;
if (typeof pic === 'undefined') {
getImages(imageDir, function (err, files) {
var imageList = JSON.stringify(files);
res.writeHead(200, {'Content-type':'application/json'});
res.end(imageList);
});
} else {
//read the image using fs and send the image content back in the response
fs.readFile(imageDir + pic, function (err, content) {
if (err) {
res.writeHead(400, {'Content-type':'text/html'})
console.log(err);
res.end("No such image");
} else {
//specify the content type in the response will be an image
res.writeHead(200,{'Content-type':'image/jpg'});
res.end(content, "binary");
}
});
}
}).listen(3333);
console.log("Server running at http://localhost:3333/");
//get the list of jpg files in the image dir
function getImages(imageDir, callback) {
var fileType = '.jpg',
files = [], i;
fs.readdir(imageDir, function (err, list) {
for(i=0; i<list.length; i++) {
if(path.extname(list[i]) === fileType) {
files.push(list[i]); //store the file name into the array files
}
}
callback(err, files);
});
}
Run this from the command line to start you new image server (assuming you named the file "server.js"):
node server.js
You should see this text appear on the command line:
Server running at http://localhost:3333/
You can quickly test it by going to this address in your browser and you should see a JSON object showing you an array of all the filenames in the "./images" directory. By the way, this program assumes you're putting the images folder in the same directory as "server.js". You can put the images directory anywhere and just change the path of the variable "imageDir".
Now you can load the list of files from Angular using this code in your controller:
$http.get("http://localhost:3333", function(data) {
$scope.images = data;
});
In your view, you can now use an ng-repeat like this to display all the images:
<div ng-repeat="image in images" style="padding: 8px">
<img src="http://localhost:3333/image={{ image }}">
</div>
Note: this will work if you run it locally on your Mac or if you upload all the images to a server on which you can use Node.js.

Download a file in Angular Environment

I need to download a file from the server. The file is stored in the database. I have a cs controller that serves a file back to UI. The server GET call looks like this:
http://server/api/controllername/fileid/data
It does work when I run that link in the Browser - the file comes down and goes into the download area (Chrome). But when I send the same command from my Angualar code I dont see any file. The console reports that my request was successful (code 200), but I just dont see anything. Please let me know what code fragments to post to make it easier to help.
Thanks
Create a link to the resource, and don't handle it with ajax.
If you make the link open in a new tab, the tab will automatically close after it realises it was just opened to download a file in most modern browsers.
Try this code:
var a = document.createElement('a');
a.href = "http://server/api/controllername/fileid/data";
a.click();
You can compose the address concatenating variables and text.
The file probably downloads correctly as a byte[] to the calling it but that would be useless to the user - as was my problem.
In my case I needed to download a file with a complex set of parameters. This example JavaScript uses a post request and creates a form (and posts it) with any JavaScript object that you give it. This code may help if you simplified it:
private open(verb, url, data, target)
{
var form = document.createElement("form");
form.action = url;
form.method = verb;
form.target = target || "_self";
if (data) {
this.createFormParameters(form, "", data);
}
form.style.display = 'none';
document.body.appendChild(form);
form.submit();
}
private createFormParameters(form, key, value) {
// recursive algorithm to add parameters (including objects and arrays of objects) to a custom form
if (typeof value === "object") {
for (var item in value) {
if (Array.isArray(value[item])) {
for (var arrayItem in value[item]) {
this.createFormParameters(form, (item + "[" + arrayItem + "]."), value[item][arrayItem]);
}
continue;
}
var input = document.createElement("textarea");
input.name = key + item;
input.value = value[item];
form.appendChild(input);
}
}
else
{
var input = document.createElement("textarea");
input.name = key;
input.value = value;
form.appendChild(input);
}
}

Download a file which does not exists in project directory in AngularJS

In my project i just wanted to implement upload and download features. I have done upload functionality with AngularJS and Node.js. But here the problem is to upload a file(.pdf, all image formats) into somewhere in the system. Say for example, my project is located in D drive. Though i have to upload a file into C drive or some other drive in my computer and i have done it successfully. But when i try to read the file location from Node.js and pass the path to angular, everything is ok and file is downloaded in the browser. when i try to open a downloaded file it sends back a response - fatal error/ nothing to show. I have tried with blob only when i send a filestream instead a path to Angular.
The code is as follows
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
where data is a file stream response from the server.
not my code but try this to save a BLOB:
var saveData = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, fileName) {
var json = JSON.stringify(data),
blob = new Blob([json], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var data = { x: 42, s: "hello, world", d: new Date() },
fileName = "my-download.json";
saveData(data, fileName);
Source: http://jsfiddle.net/koldev/cw7w5/
If you want to force the download of a linked file you could use the HTML5 a option download
<a download="filename_for_download" href="path/to/the/file"> Clicking o will force a download</a>
Some more information: https://developers.google.com/web/updates/2011/08/Downloading-resources-in-HTML5-a-download?hl=en
keep the (not existing) support of older browsers in mind
One Note: Your upload process ("to upload a file into C drive or some other drive in my computer") sounds like it may be improved or rethought.

Resources