Template.autorun vs helper for collaboration

Some of you know I recently launched https://honoringthem.com and one feature it has is real-time collaboration to allow multiple people to work on a memorial together. This is actually the only area where I’m doing pub/sub, the rest is Methods.

Right now I have my subscription housed within an autorun. Something like:

Template.someTemplate.onRendered(function(){
    import('./some-imports.js').then((modules)=>{
        // bringing in scripts for lightboxes, Quill, etc 
        ({lightGallery, lgHash, lgShare, lgThumbnail, Quill, Sortable, WaveSurfer} = modules);
        
        this.autorun(()=>{
            const token = FlowRouter.getParam('token');
            if(Meteor.userId() && token && token !== 'new'){
                this.subscribe('somePublication', token, ()=>{
                    // perform initial logic and then set a Session variable that will relate to a helper

Of the various features/sections people can add to a memorial, they’re simply stored in an array. And depending on the feature, I may need to instantiate a lightbox (for images), or in the case of the Obituary section, I need to instantiate a Quill JS editor.

So in my helper it looks sort of like:

Template.someTemplate.helpers({
    someHelper: function() {
        let token = FlowRouter.getParam('token');
        if(Meteor.userId() && token && token !== 'new'){
            let memorial = Memorials.findOne();
            if(memorial){
                // run some checks to see if the ordering of sections has changed
                // if so we need to instantiate things like lightboxes, Quill editor, etc. 

For the most part, this is all working. My helper does a lot of checks each time the data changes. For example, if a collaborator moved a photos section to come before the Obituary, then for all collaborators currently working in real-time, I need to instantiate lightbox functionality for the newly ordered photos section, and likewise the Quill editor would have been destroyed and would need to be re-instantiated.

The issue: on annoyingly rare and difficult to troubleshoot conditions, the Quill editor will be instantiated twice, resulting in two toolbars. In trying to narrow down the issue, I’m seeing that my helper above is being called dozen of times, which makes it more challenging to debug.

I’ve tried to move all my helper logic to within .autorun, so that the helper just returns the contents of a Session variable, but the autorun only seems to fire once when the Template is rendered, not each time the data changes in the subscription.

Any insight on whether my approach is good or bad, and/or how to make .autorun work in my scenario?

As a quick workaround could you not just check if Quill is not yet installed and only install it in that case?

1 Like

No workaround needed, really. I have it working. It’s just that in rare occasions the editor gets two toolbars and it’s hard to track down why because the helper re-runs so many times. That’s why I was aiming to get it working in autorun so that (ideally) I’ll see fewer re-runs.

My last resort on these cases and I don’t have the time to investigate, I just debounce() the function that includes the checking if it was already loaded.

1 Like

Finally solved it and am happy with the result. In my Template code above, I was doing a dynamic import, then subscribing (which only happens once if I’m not mistaken), then trying to do logic. Despite the this.autorun, my logic only ran once, whereas my helper would run numerous times (making it hard to debug).

Changed my Template code to run the dynamic import, subscribe, and autorun callback all separately. As of now, the autorun is called on each change, and my logic to determine whether to re-instantiate Quill, lightbox, etc is just run once instead of dozens of times like it was doing in the helper.

Was a little rusty with the use of pub/sub. Methods are so much easier to manage.