I’m trying to upload a picture taken with mdg:camera on the client to s3 and then store the image URL in mongo with some other user input using autoform. I can get the file to s3 using Meteor.call, and can print out the s3 URL on the server console. But it seems to behave in a synchronous mode and my callback data doesn’t get returned, even when specifying the async version. I’ve instrumented timers on each side and compared time stamps and the client message prints out immediately.
Q1: is this the best approach? I suspect it might be a race condition, since the user could be ready to submit the form before the fileURL comes back.
Q2: what am I doing wrong with the callbacks?
Thanks!
Template.reportIssue.events({
‘click .capture’: function(){
MeteorCamera.getPicture({}, function(error,data) {
Meteor.call(‘base64tos3’, data, function(err,results) {
if (err) {
console.log(‘error in base64 call’+err.message);
} else {
console.log('reportIsue S3 url = '+results);
Session.set(‘imageURL’,results);
}
}
);
});
}
if (Meteor.isServer) {
Meteor.methods({
‘base64tos3’ : function(photo, clientcallback){
/* … */
AWS.config.update({accessKeyId: AWS_KEY_ID, secretAccessKey: AWS_SECRET_KEY, region: AWS_REGION});
buf = new Buffer(photo.replace(/^data:image/\w+;base64,/, “”),‘base64’)
str = +new Date + Math.floor((Math.random() * 100) + 1)+ “.jpg”;
var params = {
Bucket: ‘xyz’,
Key: str,
Body: buf,
ACL:‘public-read’,
ContentEncoding: ‘base64’,
ContentType: ‘image/jpeg’
};
var s3 = new AWS.S3();
s3.putObject(params, function(err, data) {
if (err) {
throw new Meteor.Error("oopsie", "Error.");
}
else {
var urlParams = {Bucket: 'xyz', Key: str};
s3.getSignedUrl('getObject', urlParams, function(err, url){
console.log('the url of the image is ' + url);
clientcallback(null,url);
});
}
});
}
});