Refresh after CollectionFS Upload

Wow, I was having this same issue with CollectionFS with uploading profile pics! I was doing the same thing with updating the user with a string of the file location. Changing it to the actual fileObj worked for me as well. You are all amazing.

I am now having a problem where I would like to crop the uploaded image to a square shape using cropper. I believe the issue is that jquery selects the image node before the new image data is loaded into the DOM. I am using .onRendered, but it is still running way before the image appears. Here is my code. Any help would be fantasatic!

userProfilePicCrop.html

<template name='userProfilePicCrop'>
{{#with profilePicImage}}
    <div class="center-align crop-container">
        <img  src="{{this.url}}" class="profileCrop"/>
    </div>
{{/with}}

userProfilePicCrop.js

Template.userProfilePicCrop.helpers({
    "profilePicImage": function(){
        return ProfilePics.findOne({_id: Meteor.user().profile.image});
    }
});

Template.userProfilePicCrop.onRendered(function() {
    $('.crop-container > img').cropper({
            aspectRatio: 1 / 1,
            autoCropArea: 0.65,
            strict: false,
            guides: false,
            highlight: false,
            dragCrop: false,
            cropBoxMovable: true,
            cropBoxResizable: true
    });
});

Here are the relevant parts of my userEdit.js file for reference. As you can see I doing the exact same thing as @korus90, I just separated things out into a bunch of tiny functions. I created the userProfilePicCrop template as a partial so that I could use .onRendered, thinking that it would fix my problem, but ideally, I would like to keep all the code for the /:user/edit view in one .js file.

Template.userEdit.events({
    "change .profileInput": function(){
        var files = createNewFsFiles(event.target.files);
        var filesWithMetadata = addMetadataToFiles(files);
        addFilesToProfilePicCollectionAndExecuteCallbacks(
            filesWithMetadata,
            updateUserProfileImage,
            openModalAndRenderUserProfilePicTemplateWithData
        );
    }
});

function createNewFsFiles(files) {
    var fsFiles = [];
    for(var index in files){
        if (files.hasOwnProperty(index)) {
            var fsFile = new FS.File(files[index]);
            fsFiles.push(fsFile);
        }
    }
    return fsFiles;
}

function addMetadataToFiles(files){
    var filesWithMetadata = [];
    for(var index in files) {
        if (files.hasOwnProperty(index)) {
            files[index].owner = Meteor.userId();
            files[index].username = Meteor.user().username;
            filesWithMetadata.push(files[index]);
        }
    }
    return filesWithMetadata;
}

function addFilesToProfilePicCollectionAndExecuteCallbacks(files, callback1, callback2) {
    for (var index in files) {
        ProfilePics.insert(files[index], function (err) {
            if (err) {
                return err;
            }
            else {
                callback1(files[index]);
                callback2(files[index])
            }
        });
    }
}

function updateUserProfileImage(image){
    Meteor.users.update({_id: Meteor.userId()}, {$set:{'profile.image': image._id}});
}

function openModalAndRenderUserProfilePicTemplateWithData(data){
    $('#photo-crop').openModal();
    Blaze.renderWithData(Template.userProfilePicCrop, data, $("#photo-crop")[0]);

}

I was able to solve my issue using this post “Get notified when a file storage completes.” Basically the idea hinges on using the ‘stored’ event that occurs on the server when the file is finished being stored. I created a new mongo collection called FileUploadVerifications and when the ‘stored’ event occurs I inserted a new document into the FileUploadVerifications collection. I then used the collection.observe() method on the client to see when the new document was added to FileUploadVerifications and executed my jquery when the new document was added. The difficult part for me is that inserting into the collection on the server side requires using .bindEnvironment and Meteor.EnvironmentVariable. These videos helped me immensely in understanding the concepts.

1 Like

Excellent I’m glad you solved your own issue. Any chance you can share your final code to get this working?

Although it’s not as much of an issue for me, it might help anyone else who stumbles across this thread!

Yes, I will post my code once I get it cleaned up a bit and make sure it is working the way I think it is.

1 Like