Search code examples
javascriptmeteormeteor-helper

Making functions specific to Meteor templates and accessible by its event handlers


Is there a way in which I can make functions that are specific to the template and accessible by the template's event handlers? I don't want to pollute the global namespace.

I came upon this problem when I first noticed that I was repeating a lot of code between my event handlers in a manner similar to this:

Template.options.events({
    "click .btn-1": function(e) {
        // do something
        var div;
        div = $(e.target);
        if (div.hasClass("active")) {
          return div.removeClass("active");
        } else {
          return div.addClass("active");
        }
      },
    "click .btn-2": function(e) {
        // do something else
        var div;
        div = $(e.target);
        if (div.hasClass("active")) {
          return div.removeClass("active");
        } else {
          return div.addClass("active");
        }
    }
});

Note that I'm not trying to find a way to combine selectors, I already know how to do that. Notice that each button does something different, but have a few lines of repeated code. I want to keep this as DRY as possible without polluting the global namespace.


Solution

  • Each file in a Meteor project has its own local scope. If you define a function in one file using function blah() { ... } or var blah = function () { ... }, it will be inaccessible outside of that file. Only blah = function () { ... } (without var) defines a true global.

    If this isn't enough, you could define the local function in an immediately-invoked function expression (IIFE):

    (function () {
        function toggleActive(div) {
            if (div.hasClass("active")) {
                div.removeClass("active");
            } else {
                div.addClass("active");
            }
        }
    
        Template.options.events({
            "click .btn-1": function (e) {
                // do something
                toggleActive($(e.target));
            },
            "click .btn-2": function (e) {
                // do something else
                toggleActive($(e.target));
            }
        });
    })();
    
    // toggleActive is inaccessible here