1

Normally we can do this in a normal object:

var obj = {
    a: 2,
    b: function() {
        return this.a;
    }
}
console.log( obj.b() );  // Output '2' in console

So we can get value of obj.a inside obj.b.

I'm trying to achieve the same thing in Meteor Blaze. In the template:

<template name="mytemplate">
    {{b}}
</template>

and in the code behind:

Template.mytemplate.helpers({
    a: 2,
    b: function() {
        return this.a;
    }
}

Rendering 'mytemplate' will NOT output '2' as expected. How can I call 'a' method from 'b' function definition?

Nathan Wilson
  • 856
  • 5
  • 12
Tacaza
  • 539
  • 1
  • 4
  • 12

1 Answers1

0

This is because your object is not preserved in any way.

See in Blaze code:

Template.prototype.helpers = function (dict) {
  for (var k in dict)
    this.__helpers.set(k, dict[k]);
};

I think that functions are also applied to the template data (using this leads you to the data passed to the template) so even the original context of your method b is kaboom since this is dynamically evaluated. The behaviour you want to achieve is not possible with this structure.

You could maybe try to bind this method to its original object obj.b = b.bind(obj) but that's hideous.
Also Blaze may not like dealing with bound functions.

To solve this use two different objects: One for the data, one for the helper methods.

var data, methods;

data = { a : 2 };
methods = { b : function() { return data.a; } };

Template.myTemplate.helpers(methods);

In a more general way avoid relying on this when not explicitly supported by the API you use... Unless you try to force your way by binding it.

Kyll
  • 7,036
  • 7
  • 41
  • 64
  • This is counter-intuitive and inconvenient, but I guess that's a trade-off to have `this` refer to the template's context data. – Tacaza Jul 29 '15 at 10:26