Perhaps i’m not understanding the full requirements but it seems like you’re going about it the hard way. It seems like you’re trying to do thing imperatively while React wants to be declarative. I think that’s root of the issue.
There is also two separate problems to solve:
- 1 upload and image and save url to the DB
- 2 update the UI when the profile data changes
For a min. let’s assume that the user can click a button and upload a photo… from this app or another. Ultimately the user.profile.avatar
field will have a URL that changes when a new photo is uploaded.
If the user profile just has a user object like this on the client:
{profile: {avatarUrl: "foo.com/bar.png"}}
then getting the UI to change the photo on change won’t be any different than updating the user’s name. If the UI re-renders we simply want the URL to be updated and the browser will re-draw the photo:
React.createClass({
mixins: [ReactMeteorData],
getMeteorData() {
return {
viewer: Meteor.user()
};
},
render() {
return (
<div>
Username: {viewer.profile.userName}
<img src={viewer.profile.avatarUrl} />
</div>
);
}
});
Make sure this bit is working before even worrying about the upload. You can use the Meteor shell to update the user avatar url to make sure it’s working. React will re-draw the photo.
Right, so now that is working the second bit is not even related to React… as you see above even the Meteor shell can allow React to update the avatar. There are several ways to upload photos and i’ve only used S3 to host them. Any other ways doesn’t make sense for most use cases.
First try to find a solution on Npm or Github and then fallback to atmosphere if needed. You can upload directly to S3 from the client, upload with the client but sign on the server, or upload the image to your server and your server uploads to S3. Unless there is some kind of security issue, just do it from the client directly.
In all cases you will get a URL on success and that can be saved to the user profile the normal way (clientside or serverside), you’re just automating the process you did with the Meteor shell.
In the past i’ve rolled my own micro lib to upload to S3 (using POST requests), but I would recommend using a library.
These look promising:
https://www.npmjs.com/package/s3-browser-direct-upload
https://www.npmjs.com/search?q=s3+upload
Then this code can live outside of the React/View layer:
// client/domains/user.js
UserDomain = {
uploadUserAvatar(userId, file) {
_uploadToS3(file, function(err, url){
Meteor.users.update(userId, {$set: 'profile.avatarUrl': url });
})
},
_uploadToS3(file, callback) {
....
},
}