Meteor-CollectionFS
Meteor-CollectionFS copied to clipboard
Callback when file is uploaded (server-side)
Hey there!
On the server, I need to know when a file has been uploaded, so that its content is available for .createReadStream.
Is there anything like the following? Couldn't find it in the docs.
/* Server */
var file = new FS.File();
file.attachData(url, function(err) {
Files.insert(file);
});
file.on('stored', function() {
// File is available for .createReadStream
});
Hi,
You indeed have a 'stored' event emitted on the server :
store = new FS.Store.GridFS("storename", {chunkSize: 1024*1024*2});
MyCollection = new FS.Collection('mycollection', {
stores: [
store
],
});
store.on("stored", function(fileObj, storeName){
console.log("YO !");
});
The following issue is very instructive on the subject : https://github.com/CollectionFS/Meteor-CollectionFS/issues/351
Hope this helps !
Hi @phsultan, thanks for your response! It really helps :)
If I get this correctly, I can only notice here that a file has been uploaded, not the file, right? I think I'll just do something like this:
collection.insert(file, function(err, res) {
store.on('stored', function(storeName, fileObj) {
// Make sure it's this file
if (res._id === fileObj._id) {
// Do something
}
});
});
Should work. What do you think?
Well, this is how I use it in my case, and I believe this should indeed work. However, maybe you should try fileObj.on("stored", func) as per aldeed's comment in the referenced issue, as it looks a better fit with your case.
This event is mentioned to be available on the server, so I guess it's worth a try for you :)
Cheers !
Just in case you were not aware of this, another approach is using the observe feature of a cursor. An example would look like: (in CoffeeScript)
cursor = collection.find()
cursor.observe
added: (doc) ->
# doc has been just added.
changed: (doc_new, doc_old) ->
# doc_old has been just changed to doc_new.
removed: (doc) ->
# doc has been just removed.
I find this way quite flexible in my application.
Node:
Here in the added event handler the file is (most likely) not uploaded yet. A check on isUploaded in the changed event handler would tell when a file is uploaded.
I got this error, if I use a callback function recommended by @phsultan :
/home/kostya/.meteor/packages/cfs_s3/.0.1.3.e4j89r++os+web.browser+web.cordova/npm/node_modules/aws-sdk/lib/request.js:32
throw err;
^
Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
at Object.Meteor._nodeCodeMustBeInFiber (packages/meteor/dynamics_nodejs.js:9:1)
at [object Object]._.extend.get (packages/meteor/dynamics_nodejs.js:21:1)
at Object.collection.(anonymous function) [as findOne] (packages/matb33_collection-hooks/collection-hooks.js:103:1)
at [object Object]._.extend.findOne (packages/mongo/collection.js:305:1)
at [object Object].onImageUploadedCallback (server/collections_server/images.js:64:1)
at [object Object].emit (events.js:117:20)
at PassThrough.<anonymous> (packages/cfs_storage-adapter/packages/cfs_storage-adapter.js:210:1)
at PassThrough.g (events.js:180:16)
at PassThrough.emit (events.js:117:20)
at Writable.<anonymous> (packages/cfs_storage-adapter/packages/cfs_storage-adapter.js:419:1)
this is solution for those who have the same issue:
filestore.on('stored', Meteor.bindEnvironment(onImageUploadedCallback, function(error){
console.log('Error bindEnvironment', error);
}));
For anyone reading as of Jan 2018. In the first solution, I found a bug in the callback argument name order:
store = new FS.Store.GridFS("storename", {chunkSize: 1024*1024*2});
MyCollection = new FS.Collection('mycollection', {
stores: [
store
],
});
// PARAMS ARE BACKWARDS!
store.on("stored", function(fileObj, storeName){
console.log("YO !");
});
The arguments are reversed in the "stored" callback and should be:
store.on('stored', function(storeName, fileObj) {
console.log(`storeName: ${storeName}`);
console.log(`fileObj: ${fileObj}`);
});
cc @phsultan