Reputation: 83
Trying to understand better how data contexts works in Meteor, as I can't figure out this problem I'm facing. Haven't found a clear answer anywhere. I have the following templates
<template name="list">
{{#each listItem}}
{{> listItemDetail}}
{{/each}}
</template>
<template name="listItemDetail">
<p>{{_id}} {{title}}</p>
<p>{{idViaHelper}}</p>
</template>
And in my Javascript I have
Template.list.helpers({
'listItem': () => {
return List.find().fetch();
})
Template.listItemDetail.helpers({
'idViaHelper': () => {
return this._id
})
As far as my understanding of data contexts within Meteor goes, using #each
sets the context for each instance of the listItemDetail
template to be a document that that is returned from the listItem
helper.
And this works as I'd expect when it comes to using {{_id}}
in the listItemDetail
template, showing the ID of the document.
But if I try to get the same _id
via a helper {{idViaHelper}}
which uses this._id
, I get undefined
. When I try console.log(this)
, it shows me that this
is referring to the Window object. But I have no idea why. What is going on and why does the data context not get picked up in the template helper?
This is my first post, thanks for your help!
Upvotes: 0
Views: 112
Reputation: 2185
Julien Leray is correct in his answer regarding lexical this
. You lose the data context when using lambda expressions. However, Meteor offers you ways to access your Template data without lexical this
, viz.:
Template.list.helpers({
'listItem': () => List.find().fetch();
});
Template.listItemDetail.helpers({
'idViaHelper': () => Template.currentData()._id
});
You can use both Template.currentData()
and Template.instance().data
.
Also, note that if you have a lambda expression that only includes a single return statement, you can use the shortcut syntax as I did above.
// ECMAScript 5
var myFunc = function (a, b, c) {
return b * a - c;
};
Becomes:
// ECMAScript 6
const myFunc = (a, b, c) => b * a - c;
Upvotes: 0
Reputation: 1687
You are right about the Meteor datacontext flow. What you are doing is working.
You only forget what the this
represent into a lambda function.
Read the the part Lexical this from MDN, it's better explained than what I could say: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
For your case, the easier way to get the datacontext directly from your this on helpers is to pass by usual anonymous function.
Just try:
Template.listItemDetail.helpers({
'idViaHelper': function(){
return this._id
})
That's it.
You've got unlucky on this one, there is no issue related to Meteor here.
Other related question you could find useful: meteor helper functions, lambdas and lexical this
Upvotes: 1