4

Works

Template.Hello.onRendered(function() {
  this.autorun(() => {
    console.log('sup');
  });
});

Doesn't work.

Template.Hello.onRendered(() => {
  this.autorun(() => {
    console.log('sup');
  });
});

The error is TypeError: _this.autorun is not a function.

Any ideas why using arrow notation gives us this error?

Simon
  • 1,681
  • 1
  • 21
  • 34
  • Possible duplicate of [Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?](http://stackoverflow.com/questions/34361379/arrow-function-vs-function-declaration-expressions-are-they-equivalent-exch) – Felix Kling Jan 25 '16 at 22:25

1 Answers1

7

Arrow functions use lexical binding of this which means that this will be whatever it was when the function was created. This means that you unfortunately can't use it when creating functions on objects that use object properties such as the template.

A small example is something like:

o = {};
o.fn = () => console.log(this);
o.fn(); // not 'o'

o.fn = function () { console.log(this); }
o.fn(); // 'o'

.autorun is a method of the template so the functional binding of this is required.

There are times when the lexical binding of arrow functions are useful such as in the callback to autorun. In that case, you want this to remain the same as the outer scope. Otherwise you would have to bind it:

Template.Hello.onRendered(() => {
  this.autorun(() => {
    console.log(this); // the template
  });
  this.autorun(function () {
    console.log(this); // the template
  }.bind(this));
  this.autorun(function () {
    console.log(this); // the callback function
  });
});
Explosion Pills
  • 188,624
  • 52
  • 326
  • 405