Unfortunately, I am not allowed to post images, so that makes it a bit harder to show the issue at hand. So I will describe it here. In my final Meteor on screen display, I have an invoice with line-items. The line-items and all work perfectly and show as expected. What I wanted to do, was "break in" in the #each-loop after 4 line-items are printed on screen, and then do something else (calculate and print sub-totals). I can't get that to work, since the session var I created for that does not seem to reactively change on every line-item. Instead, it seems to hold the last value from the complete #each loop.
Note, that there is a listindex variable in there that perfectly re-actively builds up from 1, to 2,3, and 4 on each line-item that is within the #each loop. So, the listindex variable does work reactively within the #each loop.
At the same time, I am introducing a session var in there, that should be "true" on line-item number 4, and "false" in all other cases. On "true" it should print "onderbreking" right in there. However, the session var always gives "true" and (because of that) always prints "onderbreking". That's not how I intended it to work of course.
I do not understand why the listindex works, and the session var does not?
Here is my javascript on this. The template is called "layout6.html":
Template.layout6.helpers({
// Bereken de index in de #each loop
listIndex: function() {
currentIndex += 1;
if(currentIndex == 4) {
Session.set('sessionPageBreak1', true);
}
if(currentIndex != 4) {
Session.set('sessionPageBreak1', false);
}
return currentIndex;
},
});
Template.layout6.SessionPageBreak1 = function() {
// Voeg de waarde van de sessie variabele toe aan de template
var data = Session.get('sessionPageBreak1');
return data;
};
The session var is initially set here:
// Session var for layoutcounter
Session.setDefault('sessionPageBreak1', false);
Session.setDefault('sessionPageBreak2', false);
Session.setDefault('sessionPageBreak3', false);
var currentIndex = 0.0;
Finally, this is the html involved on layout6.html:
{{#each factuur6.lineItems}}
{{listIndex}}
{{SessionPageBreak1}}
{{#if SessionPageBreak1}}
<div><p>onderbreking</p></div>
{{/if}}
And of course, there is a {{/each}} statement as well, but there is a lot of code in between that is not very relevant for this issue, so I did not put it in here.
I hope I included everything, if not, you guys doubtlessly will tell me.
The question is: what am I doing wrong, so that the session var is not reactively changing within the #each loop?
This isn't really the right way to use Session variables. Session variables are for global application state, not for storing intermediate values through a single computation. The general rule is that templates and template helpers should not have side-effects (like setting Session variables).
I would take a different approach. Define a helper:
lineItemsWithIndex: function () {
return _.map(this.factuur6.lineItems, function (item, index) {
var newItem = _.clone(item);
newItem.index = index;
return newItem;
});
}
This function returns a copy of this.factuur6.lineItems
, except each object has an index
property added to it. For example, if the list of lineItems
is [{name: "foo"}, {name: "bar"}, {name: "baz"}]
, we return [{name: "foo", index: 0}, {name: "bar", index: 1}, {name: "baz", index: 2}]
. The original list is unchanged. If factuur6
is a helper rather than a field, then instead use _.map(Template.layout6.factuur6().lineItems ...
.
Then iterate over that in your template:
{{#each lineItemsWithIndex}}
{{index}}
{{pageBreak1}}
{{#if pageBreak1}}
<div><p>onderbreking</p></div>
{{/if}}
{{/each}}
Where pageBreak1
is a helper function () {return this.index == 3;}
(3 rather than 4, since these indices are 0-based). Since we added the index to each object, it is now accessible in the helper.
This assumes that your line items don't already have a field called index
.