I am using MeteorJs, MongoDB and React. I want to simply make a module to upload/download files and store them in a MongoDB collection. So far, I can upload the file but I don't know how to download it.
This is the method in server:
Meteor.methods({
'saveFile': function(one){
ChivoFiles.insert({data:one.buffer})
}
});
This is the upload in client:
uploadFile(event) {
var file = event.target.files[0]; //assuming 1 file only
if (!file) return;
var reader = new FileReader(); //create a reader according to HTML5 File API
reader.onload = function(event){
var elBuffer = new Uint8Array(reader.result) // convert to binary
const one= {buffer: elBuffer}
Meteor.call('saveFile', one);
}
reader.readAsArrayBuffer(file);
}
<input type="file" id="fileinput" disabled={this.state.inProgress} ref="fileinput" onChange={this.uploadFile}/>
And this is how it look in MongoDB Compass:
I would like to know how I can convert the Mongo document into a downloadable file. Thanks
Problem here is the following:
the saved data is an EJSON format of binary. What you need to do is, is to create an HTTP endpoint, get the doc and manually link the data to an http route:
import { WebApp } from 'meteor/webapp'
WebApp.connecthandlers.use('/download', (req, res) => {
const file = ChivoFiles.findOne(req.query.id)
const binary = file.data
res.writehead(200, {
'Content-disposition': `attachment; filename=${file.name}`
'Content-type': file.mimetype
}); // this is why you need to save the name and mime, too
const filestream = fs.createReadStream(binary);
filestream.pipe(res);
})
You can call this via HTTP GET /download?id=01234567890
There is very popular Meteor-Files package, which handles file upload, download, permission etc.
It's the perfect solution for your use-case.
You can use it together with external storages (S3 etc.) or local storages (FileSystem, GridFs): https://github.com/veliovgroup/Meteor-Files/blob/master/docs/3rd-party-storage.md
It also represents your files as documents in a Mongo.Collection
, so you can access file information and meta data, without actually downloading the files.
Downloading files is handled via MyFilesCollection.link(fileDoc._id)
which creates a http-based download link for the file, represented by the fileDoc (which itself is created on upload).