Accessing template helper dictionary in Meteor event handler
Asked Answered
T

2

5

In Meteor, I'm sending two objects from my db to a template:

Template.myTemplate.helpers({
  helper1: function() {
    var object1 = this;  // data context set in iron:router...path is context dependent
    // modify some values in object1
    return this;
  },
  helper2: function() {
    return Collection2.find({_id: this.object2_id});
  }
});

This template also has an event handler to modify the two objects above. I am trying to access helper1 and helper2 from above, but if I call the data context of the template, I only get access to the unmodified version of object1. How do I access the helpers defined above?

Template.myTemplate.events({
  'submit form': function(event) {
    event.preventDefault();
    // Access helper2 object and attributes here instead of calling Collection2.find() again
  }
});
Tartarus answered 15/1, 2015 at 11:36 Comment(5)
There's no way to call helpers with the current public API.Salvation
Peppe, you might know this, but I just found out there is an internal api for accessing helpers - Template.myTemplate.__helpers.get('helper');Tartarus
Given this is internal, I assume the api may change in the future, thus it may not be the best idea to use this often in your code.Tartarus
Just remember that you can't rely on using this in the helpers you call this way, and I guess Template.instance() won't work neither, unless you do some more public API violations.Salvation
@bgmaster, Template.myTemplate.__helpers.get('helper'); is way too hacky, and can get obsolete at any moment in the future. Blaze is not designed to be used this way ... check my answer belowAlliteration
R
4

Helpers are just functions and thus can be passed around and assigned to other variables at will, so you could define a function and then assign it the helper2 key of the template helpers and call by it's original reference from the event handler.

var helperFunction = function() {
    return Collection2.find({_id: this.object2_id});
};

Template.myTemplate.helpers({
    helper1: function() {
        var object1 = this;  // data context set in iron:router...path is context dependent
        // modify some values in object1
        return this;
    },
    helper2: helperFunction
});

Template.myTemplate.events({
    'submit form': function(event) {
        event.preventDefault();
        var cursor = helperFunction();
    }
});
Rhomb answered 15/1, 2015 at 14:20 Comment(2)
Thanks. This pattern helps a little with avoiding repeating code, which I was aiming to do. The only thing I would note is this in the function can change. When you call the function in the event handler, this becomes the Window object instead of the data context. I find this odd considering this in the event handler is still the data context. If you can update your answer to reflect this, I'll mark it as correct.Tartarus
As @Tartarus has noted, you need to call the call method and provide the thisArg instead of simply calling the function. However, in the event, you don't know what the thisArg should be (and it may be different different times {{helper2}} has been used, so this doesn't work in general).Salvation
A
0

If you can modify helpers from events, then, any part of the Meteor application can do, which is against the design philosophy of Blaze!

Blaze is designed to be uni-directional data binding tempting system. What you ask for can be achieved using Angular (used on its own, or side by side with Blaze, look at THIS), which is by nature a 2-way data binding tempting system.

You may also want to check React, which is also a 2 way data binding

Alliteration answered 29/10, 2015 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.