Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload Data to Meteor / Mongo DB

I have a Meteor app and would like to upload data (from csv) to a meteor collection.

I have found:

  • solutions (e.g. Collectionfs) which deal with file uploads
  • methods for uploading directly to the underlying mongo db from the shell
  • references to meteor router - but I am using the excellent iron-router, which does not appear to provide this functionality

My requirement is that the app user be able to upload csv data to the app from within the app. I do not need to store the csv file anywhere within the app file structure, I just need to read the csv data to the collection.

It is possible that I cannot figure out how to do this because my terms of reference ('upload data to meteor') are ambiguous or incorrect. Or that I am an idiot.

like image 694
Alex Webster Avatar asked Jan 10 '14 19:01

Alex Webster


2 Answers

ChristianF's answer is spot on and I have accepted it as the correct answer. However, it provides even more than I need at this stage, so I am including here the code I have actually used - which is largely taken from Christian's answer and other elements I have found as a result:

HTML UPLOAD BUTTON (I am not including drag and drop at this stage)

<template name="upload">
  <input type="file" id="files" name="files[]" multiple />
  <output id="list"></output>
</template>

JAVASCRIPT

Template.upload.events({
  "change #files": function (e) {
    var files = e.target.files || e.dataTransfer.files;
    for (var i = 0, file; file = files[i]; i++) {
      if (file.type.indexOf("text") == 0) {
        var reader = new FileReader();
        reader.onloadend = function (e) {
          var text = e.target.result;
          console.log(text)
          var all = $.csv.toObjects(text);
          console.log(all)
          _.each(all, function (entry) {
            Members.insert(entry);
          });
        }
        reader.readAsText(file);
      }
    }
  }
})

NB there is a jquery-csv library for Meteor here: https://github.com/donskifarrell/meteor-jquery-csv

like image 87
Alex Webster Avatar answered Sep 22 '22 05:09

Alex Webster


I've solved this problem in the past using this gist of mine, together with this code (using the jquery-csv plugin to parse the csv data). This is done on the client side and is independent of using iron-router or not. It would be fairly straightforward to move the insertion code into a Meteor method, uploading the csv file first and then parsing and inserting the data on the server. I've tried that, too, but didn't see any performance improvement.

$(document).ready(function() {
    var dd = new dragAndDrop({
        onComplete: function(files) {
            for (var i = 0; i < files.length; i++) {
                // Only process csv files.
                if (!f.type.match('text/csv')) {
                    continue;
                }
                var reader = new FileReader();
                reader.onloadend = function(event) {
                    var all = $.csv.toObjects(event.target.result);
                    // do something with file content
                    _.each(all, function(entry) { 
                         Items.insert(entry);
                    });
                }
             }
        }
     });

     dd.add('upload-div'); // add to an existing div, turning it into a drop container
});

Beware though that if you are inserting a lot of entries, then you are better off turning all reactive rerendering off for a while, until all of them are inserted. Otherwise, both node on the server and the browser tab will get really slow. See my suggested solution here: Meteor's subscription and sync are slow

like image 39
Christian Fritz Avatar answered Sep 26 '22 05:09

Christian Fritz