I have create a zip file in server side, then I would like to pass the file to client side so that I can download it with the saveAs() function and put it into a new Blob() function. How can I do that?
const blob = new Blob([res.file], { type: 'application/zip' });
saveAs(blob, res.filename);
I create a code like that, but I cant convert a right type of buffer file for the zip in server.
How should I convert the zip file so that the client side can receive a right file type input in Blob function.
Once you get your zip ready, you can serve the file using download() method to achieve that
Below snippet will help you
res.download('/report-12345.pdf', 'report.pdf', function (err) {
if (err) {
// Handle error, but keep in mind the response may be partially-sent
// so check res.headersSent
} else {
// decrement a download credit, etc.
}
})
You can read more details here
http://expressjs.com/en/5x/api.html#res.download
Hope that will help you :)
Related
I'm trying to create pages that will take a user information and save them to the database. the user information are {name, age....... picture}, when I put the information without a picture it work fine and the data saved to the database but when I try to put the picture with them it gives me the error.
I'm sorry for the picture quality.
any one can help me with this.
I'm using nodejs and react
thx :)
You would need to send the picture as Base64 in your object, as it follows:
var data = {
name: 'John',
age: 27,
picture: 'data:image/png;base64,R0lGODlhPQBEAJos...',
}
In NodeJS, if using Express, the picture will be req.body.picture. So, all you need to do is store the file, then get the temp path do do what you need.
You can store base64 file doing:
var filePath = './tmp/myPicture.png';
fs.writeFile(filePath, req.body.picture, 'base64', (err) => {
if (err) {
res.json({ err: 'Error while creating temp file from base64.' });
} else {
// Your file was uploaded, so you can read your file here.
}
});
I'm quite confused on how to use the Amplify library to actually download an mp3 file stored in my s3 bucket. I am able to list the bucket contents and parse it all out into a tree viewer for users to browse the various files, but once I select a file I can't get it to trigger a download.
I'm confident my amplify configuration is correct since I can see all my expected directories and when I select the file I want to download, I see the response size being correct:
You can see it takes 2+ seconds and appears to be downloading the data/mp3 file, but the user is never prompted to save the file and it's not in my Downloads folder.
Here is a capture of my file metadata setup from my bucket:
And the method I'm calling:
getFile (fileKey) {
Storage.get(fileKey, {download: true})
}
Without the "download : true" configuration, I get the verified URL back in the response. I'd like to avoid making a 2nd request using that URL download the file if possible. Anything else I may have missed? Is it better for s3 operations to go back to the standard aws-sdk? Thanks in advance!
I ended up using a combination of this answer:
https://stackoverflow.com/a/36894564
and this snippet:
https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
So the file gets downloaded in the response data(result), I added more meta data tags to the files to get the file name and title. Finally adding the link to the DOM and executing a click() on it saves the file named correctly. Full solution below:
getFile (fileKey) {
Storage.get(fileKey, {download: true}).then(result => {
console.log(result)
let mimeType = result.ContentType
let fileName = result.Metadata.filename
if (mimeType !== 'audio/mp3') {
throw new TypeError("Unexpected MIME Type")
}
try {
let blob = new Blob([result.Body], {type: mimeType})
//downloading the file depends on the browser
//IE handles it differently than chrome/webkit
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName)
} else {
let objectUrl = URL.createObjectURL(blob);
let link = document.createElement('a')
link.href = objectUrl
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
} catch (exc) {
console.log("Save Blob method failed with the following exception.");
console.log(exc);
}
})
}
}
I'm using node to respond clients with two files. For now, i'm using a endpoint for each file, cause i can't figure out how pass more than one in a row.
Here's the function that responds with the file:
exports.chartBySHA1 = function (req, res, next, id) {
var dir = './curvas/' + id + '/curva.txt'; // id = 1e4cf04ad583e483c27b40750e6d1e0302aff058
fs.readFile(dir, function read(err, data) {
if (err) {
res.status(400).send("Não foi possível buscar a curva.");
}
content = data;
res.status(200).send(content);
});
};
Besides that, i need to change the default name of the file, when i reach that endpoint, the name brings 1e4cf04ad583e483c27b40750e6d1e0302aff058, but i'm passing the content of 'curva.txt'.
Someone has any tips?
Q: How do I pass back contents of more than one file back to a user without having to create individual endpoints.
A: There are a few ways you can do this.
If the content of each file is not huge then the easiest way out is to read in all of the contents and then transmit them back as a javascript key-value object. E.g.
let data = {
file1: "This is some text from file 1",
file2: "Text for second file"
}
res.send(data);
res.end();
If the content is particularly large then you can stream the data across to the client, while doing so you could add some metadata or hints to tell the client what they are going to receive in the next moment and when is the end of file.
There is probably some libraries which can do the latter for you already, so I would suggest you shop around in github before designing/writing your own.
The former method is the easiest.
I'm having some issues trying to request an image file from Cloud Clode in Parse.
This is my Parse Cloud Code:
Parse.Cloud.define("datata", function(request, response) {
//var message = request.params.message;
var file = request.params.file;
//console.log(file);
var base64 = file.toString("base64");
var data = new Parse.File("test.jpg", {
base64: base64
});
data.save().then(function() {
// The file has been saved to Parse.
console.log("WIN");
}, function(error) {
console.log("LOSE");
// The file either could not be read, or could not be saved to Parse.
});
});
The problem is when I try to post the file I got this as an answer from the server:
{"code":107,"error":"invalid utf-8 string was provided"}
I'm trying to create custom endpoints for some custom hooks, that why I'm working with Cloud Code.
Anyone have any idea about how can I create and endpoint in Parse Cloud Code for requesting and creating files?
Thanks in advance.
What JSON response did you get when you POST'd the file?
You need to use the "url" value in order to GET the file.
{"__type":"File","name":"e580f231-90ba-4d24-934c-7f9e7c8652d6-picf1","url":"http://files.parse.com/1315e4d8-f302-4337-adbe-d8650ab5c312/e580f231-90ba-4d24-934c-7f9e7c8652d6-picf1"}
So, in the example above which is very similar to the response when a file type is POST'd, you would use the value of the "url" tag in a http/GET.
So i see this code on the Docs
Template.myForm.events({
'change .myFileInput': function(event, template) {
FS.Utility.eachFile(event, function(file) {
Images.insert(file, function (err, fileObj) {
//Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
});
});
}
});
But i dont want the file upload inmediatly when i click "myFileInptu" , i want to store that value (from the input), and insert lately with a button, so there is some way to do this?
Also its there a way to upload a FSCollection without a file? just metadata
Sorry for bad english hope you can help me
Achieving what you want to requires a trivial change of the event, i.e switching from change .myFileInput to submit .myForm. In the submit event, you can get the value of the file by selecting the file input, and then storing it as a FS File manually. Something like:
'submit .myForm': function (event, template) {
event.preventDefault();
var file = template.find('#input').files[0];
file = new FS.File(file);
// set metadata
file.metadata = { 'caption': 'wow' };
Images.insert(file, function (error, file) {
if (!error)
// do something with file._id
});
}
If you're using autoform with CollectionFS, you can put that code inside the onSubmit hook. The loop you provided in your question works also.
As for your second question, I don't think FS.Files can be created without a size, so my guess is no, you can't just store metadata without attaching it to a file. Anyways, it seems to me kind of counterintuitive to store just metadata when the metadata is supposed to describe the associated image. You would be better off using a separate collection for that.
Hope that helped :)