5

I am using Meteor CollectionFS. Currently my file uploading is performed on client. I want to perform file uploading on server so that other platforms like andriod or ios can use my services of file uploading.

Currently here is my code:

client.html

<input type="file" custom-on-change="uploadFile">

clientController.js

app.controller('clientController', function ($scope, $meteor, $filter) {

    $scope.uploadFile = function(event){

        var files = event.target.files;

        for (var i = 0, ln = files.length; i < ln; i++) {

            files[i].userId = Meteor.userId();

            Images.insert(files[i], function (err, fileObj) {

            });
        }
    };
});
app.directive('customOnChange', function() {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      var onChangeHandler = scope.$eval(attrs.customOnChange);
      element.bind('change', onChangeHandler);
    }
  };
});

Schema.js

Images = new FS.Collection("images", {
    stores: [
      new FS.Store.FileSystem("images", {path: '~/uploads'})
    ]
});

The code works perfect for me. But as you see everything is done in the client controller. How can I perform this on server controllers in Meteor?

How can I send my file to the server so that I can process, insert or upload my images there?

EDIT

As you know that an Android App will be sending a base64 encoded string. So how will I treat that here? I want to have a centralized function for Image Uploading on Meteor Server.

StormTrooper
  • 1,731
  • 4
  • 23
  • 37
  • I don't quite understand your question. You are already sending the file to the server. Is this code not working in a cordova app? – Serkan Durusoy Dec 18 '15 at 19:16
  • @SerkanDurusoy This code is working perfect for web. But as you see all the code is placed on client. What if an android app wants to use my image uploading method? He will offcourse sends a base64 encoded string. So how will I treat that? – StormTrooper Dec 20 '15 at 04:02

1 Answers1

2

You can place that logic inside a Meteor Method. Then you can decide if you want that method to run only on the server or both on the client and the server (latency compensation).

So I would change your controller to:

$scope.uploadFile = function(event){
  Meteor.call("uploadFiles", event.target.files);
};

Schema.js (or any other file which can run on server or client and server - read more about Meteor file structure here)

Images = new FS.Collection("images", {
    stores: [
      new FS.Store.FileSystem("images", {path: '~/uploads'})
    ]
});

Meteor.methods({
  uploadFiles: function (files) {

    for (var i = 0, ln = files.length; i < ln; i++) {
        files[i].userId = Meteor.userId();

        Images.insert(files[i], function (err, fileObj) {
        });
    }

  }
});

The method can also return values, run on server and client. I would also read more about Meteor Methods on the Meteor guide.

Urigo
  • 3,175
  • 21
  • 27
  • I want to ask two things here. Are you sure we can pass event.target.files (A FILE OBJECT) to a server function? And as you know an android app will be sending a base64 encoded string not a file obj. So how will I handle that? – StormTrooper Dec 20 '15 at 04:05
  • I tried that way. I get empty object of files in Meteor.methods. Like this: { '0': {} } – StormTrooper Dec 21 '15 at 05:09
  • Yes I wrote a general thing, it's not a complete solution but I hope you get the idea – Urigo Dec 21 '15 at 10:34
  • @HassanSardar you could pass only the file URL (because you use filesystem) and save that or only the id if you were using gridfs which I recommend after painful times with filesystem. definitely easier and better for production IMO – Luna Dec 22 '15 at 01:29
  • Well I have managed the file uploading with simple filesystem module. Thanks for all the help. I have another question if you can take a look at that as well: http://stackoverflow.com/questions/34527629/to-which-directory-images-or-files-should-be-uploaded-in-meteor – StormTrooper Dec 30 '15 at 10:32