Template Data Context to use with metadata OR How to use it with Template...events() ?
juliomac opened this issue · 6 comments
My app is working fine for upload using the code from examples.
However, the examples are placing the code on Meteor.startup(). I need to get information from the template Data context in order to fill in the metadata fields. In Meteor.startup() I don't get the information.
For instance, iron-router renders me a template with CityId="nyc". I want to upload photo with metada CityId="nyc". It seems like I can only setup metadata once at startup or onRendered.
See the code I am trying to use:
var dataContext = Blaze.getData(Blaze.currentView);
var owner = Meteor.userId();
var CityId = dataContext._id;
CityPhotosGridFS.resumable.on('fileAdded', function (file) {
CityPhotosGridFS.insert({
_id: file.uniqueIdentifier,
filename: file.fileName,
contentType: file.file.type,
metadata: {
owner: owner,
CityId: CityId
}
},
function (err, _id) {
if (err) { return console.error("File creation failed!", err); }
CityPhotosGridFS.resumable.upload();
}
);
});
This myfile.resumable.om('filAdded'
, ... confuses me I guess. Is there a way to use it with standard Template...events() ?
You can probably define the resumable.on(...)
handlers in the template onRendered()
callback. Just do it before you setup the resumable assignDrop
(and/or assignBrowse
) DOM target element.
So, for example here: https://github.com/vsivsi/meteor-file-sample-app/blob/master/sample.coffee#L26
Hi @vsivsi ! Thanks for the prompt support!
I have done like you suggested. I have put both assignDrop
and resumable.on
inside onRendered()
.
The problem is that the metadata is not updated! It picks up the data of the first time it rendered only. For example, if I first render for CityId= "nyc" and later go to page with CityId="Boston", the metadata will not be updated. It will still show CityId= "nyc".
Meteor simply don't pass again though function onRendered()
where we placed the resumable.on()
function.
I also tried having resumable.on()
inside a template...helper()
, which is always re-run. But it gives errors and upload files with zero size.
I laso tried using this.autorun(function()
trick inside onRendered to force it to re-run as suggested HERE.
In fact it works nicely and re-runs part of the code. However, nothing inside resumable.on
is re-run. Thus, metadata keeps immutable once define for the first time.
This is what I did:
Template.Cities.onRendered(function () {
this.autorun(function() {
Template.currentData();
var dataContext = Blaze.getData(Blaze.currentView); // Could use either currentData or Blaze to get context
var owner = Meteor.userId();
var CityId = dataContext._id;
CityPhotosGridFS.resumable.on('fileAdded', function (file) {
console.log("passed here once"); // console shows this only once despite autorun()
CityPhotosGridFS.insert({
_id: file.uniqueIdentifier,
filename: file.fileName,
contentType: file.file.type,
metadata: {
owner: owner,
CityId: CityId
}
},
function (err, _id) {
if (err) { return console.error("File creation failed!", err); }
CityPhotosGridFS.resumable.upload();
}
);
});
});
});
I didn't realize that the metadata could change after rendering... in that case you are gong to need to find a way to make your up-to-date metadata available to the resumable handler functions. I think you are on the right track with the code above.
Declaring a variable to hold a metadata object visible to the scope where the resumable handlers are declared. Then keep it updated using template autorun or helper functions. You don't want to redeclare the fileAdded handler in the autorun though. You should declare the shared variable in the onRendered, keep it updated in the autorun, and use it in the fileAdded handler.
Sorting out variable scoping like this is a JavaScript / Meteor client / resumable.js programming question that has nothing really to do with file-collection itself. (Resumable.js is an independent project).
I'm happy to help, but answering basic programming questions like this in a github issue without understanding the whole scope of your app and its requirements is going to be of limited usefulness.
Thanks @vsivsi, taking the fileAdded
handler out of the autorun()
loop did the trick.
So far could only pass the shared variable to the resumable.on callback function as global as they are not visible outside autorun()
. Not very elegant, but works. Passing as extra arguments to the resumable.on('fileAdded')
callback does not work either.