Last Updated: February 25, 2016
·
26.9K
· drgorb

File Upload with Meteor method

Using the excellent Jasny edited BootStrap library, it is very easy to create an upload button which sends the contents of a file to a Meteor.method

First create the file upload button:

<div class="fileupload fileupload-new" data-provides="fileupload">
   <span class="btn btn-file">
      <span class="fileupload-new">{{file-upload.label.de}}</span>
      <span class="fileupload-exists">Andere</span>
      <input name="{{file-upload.name}}" class="file-upload-input" method="{{file-upload.method}}" type="file"/>
   </span>
   <span class="fileupload-preview">
   </span>
   <a href="#" class="close fileupload-exists" data-dismiss="fileupload" style="float: none">×</a>
</div>

In my example, all file upload fields have a common class file-upload-inputwhich is used to create the event.

In the template's javascript you have to provide the event:

"change .file-upload-input": function(event, template){
   var func = this;
   var file = event.currentTarget.files[0];
   var reader = new FileReader();
   reader.onload = function(fileLoadEvent) {
      Meteor.call('file-upload', file, reader.result);
   };
   reader.readAsBinaryString(file);
}

in this example, the files get uploaded as soon as they are selected. There is still the option of changing one's selection.

On the server, the file-upload method is very simple:

Meteor.methods({
   'file-upload': function (fileInfo, fileData) {
      console.log("received file " + fileInfo.name + " data: " + fileData);
      fs.writeFile(fileInfo.name, fileData);
   }
});

This will store the file in the default location. If you need to put it somewhere else, you need to specify the path.

But if you are serious about file upload, check out (and possibly contribute to) the meteorite package https://github.com/raix/Meteor-CollectionFS

11 Responses
Add your response

Thanks! Just to indicate a typo, the name of your method on the server should be 'file-upload' not 'upload-payment'. :)

over 1 year ago ·

thank you Julian. I have corrected the method name

over 1 year ago ·

Thanks Micha, it works great.

For binary files (like pdf) I added server side decode:
fs.writeFile(fileInfo.name, fileData, new Buffer(fileData, 'binary'));

over 1 year ago ·

Upload is working fine here, but the images are not valid.
I inspected the bytecode and saw that are 2 extra bytes added at the beginning?
Any idea whats going wrong please?

over 1 year ago ·

@daslicht did you follow pascoual's tip? I guess it is required if you have a binary file like an image.

over 1 year ago ·

yeah its still broken

over 1 year ago ·

thats working for me so far:
http://georgeinenglish.com/upload-files-meteor-js/

Is you appoach working for you ? still with the latest version of meteor ?

over 1 year ago ·

Thanks for the post.

  • 'fileInfo.name' in the server side is getting displayed as undefined. Can you please check on this and tell me how can I get the filename in server side?

  • I would like to correct the binary buffer data writing suggestion given by pascoual. The code that worked for me is fs.writeFile(fileNameWithPath, new Buffer(fileData, 'binary')); Here fileNameWithPath is var defined by me which contains filename with path.

over 1 year ago ·

as to your question: the fileInfo is passed from the client. If there is no name, then the client did not provide it.
The Meteor method does not care where the data comes from. You could just as well use this method the store some user input in a file on the server.
My point is: check the call on the client.

You might get more answers by posting your question on stackoverflow

over 1 year ago ·

Does this example use Collection-FS? I get Uncaught referenceError: fs is not defined. Should I use another meteor package, or does any other package work with this? Thanks!

over 1 year ago ·

@dshaw002: it uses node's File System (http://nodejs.org/api/fs.html)

over 1 year ago ·