Handlebar doesn't render a collection field correctly - collections

I'm having problem trying to use a collection field named created in a template. Is that a reserved word, or something?
The part of the template that's struggling looks like this:
{{#each threads}}
<tr>
<td>{{topic}}</td>
<td>{{creator.username}}</td>
<!-- The line below is the evil one. -->
<td>{{created}}</td>
<td>{{lastPost.poster.username}} {{datetime lastPost.posted}}</td>
</tr>
{{/each}}
The threads I find in my console in my browser are the following:
[
Object
_id: "ngEtonq8XM36KtG3S"
created: 1375881336372
creator: function (){
creatorId: "ZmKpMdhP4GtzQo98e"
lastPost: function (){
posts: function (){
subCategory: function (){
subCategoryId: "axgd2xzctkfmphmwM"
topic: "Testing"
__proto__: Object
,
Object
_id: "XafEMvAvcRzpBKxG3"
created: 1375882602652
creator: function (){
creatorId: "ZmKpMdhP4GtzQo98e"
lastPost: function (){
posts: function (){
subCategory: function (){
subCategoryId: "axgd2xzctkfmphmwM"
topic: "Testnign again"
__proto__: Object
,
Object
_id: "CZmf5MfqZrB28SLPB"
created: 1375883440242
creator: function (){
creatorId: "ZmKpMdhP4GtzQo98e"
lastPost: function (){
posts: function (){
subCategory: function (){
subCategoryId: "axgd2xzctkfmphmwM"
topic: "And another shoot"
__proto__: Object
]
Obviously three threads, and they all have a created field. But the browser shows the following:
<tr>
<td>And another shoot</td>
<td>Peppe L-G</td>
<td></td>
<td>Peppe L-G 7 August 2013 15:50</td>
</tr>
<tr>
<td>Testnign again</td>
<td>Peppe L-G</td>
<td></td>
<td>Peppe L-G 7 August 2013 15:36</td>
</tr>
<tr>
<td>Testing</td>
<td>Peppe L-G</td>
<td></td>
<td>Peppe L-G 7 August 2013 15:35</td>
</tr>
Why isn't the created field showed?
I tried to use <td>{{this.created}}</td> instead of <td>{{created}}</td>, and then the browser shows the following:
<tr>
<td>And another shoot</td>
<td>Peppe L-G</td>
<td>1375883440242</td>
<td>Peppe L-G 7 August 2013 15:50</td>
</tr>
<tr>
<td>Testnign again</td>
<td>Peppe L-G</td>
<td></td>
<td>Peppe L-G 7 August 2013 15:36</td>
</tr>
<tr>
<td>Testing</td>
<td>Peppe L-G</td>
<td></td>
<td>Peppe L-G 7 August 2013 15:35</td>
</tr>
The created field now works for the first thread, but not the rest. What's going on?!
In case it's relevant, here's the entire template:
<template name="pageForumSubCategory">
<div class="layoutContentForumSubCategory">
{{#with subCategory}}
<h1>
Forum
→
{{name}}
{{#if currentUser}}
→
New thread
{{/if}}
</h1>
{{#if threads.count}}
<table border="2">
<thead>
<tr>
<th>Topic</th>
<th>Creator</th>
<th>Created</th>
<th>Last post</th>
</tr>
</thead>
<tbody>
{{#each threads}}
<tr>
<td>{{topic}}</td>
<td>{{creator.username}}</td>
<!-- The line below is the eveil one. -->
<td>{{this.created}}</td>
<td>{{lastPost.poster.username}} {{datetime lastPost.posted}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<p>Well, it's more or less empty here (so far).</p>
{{/if}}
{{else}}
<h1>
Forum
→
???
</h1>
<p>Hmm... There is no subforum with the given id. Strange, but there's nothing I can do about it. Sorry.</p>
{{/with}}
</div>
</template>

All templates already have a created property, which is callback (run when your template is created). The easiest solution is just to call the field something else like createdAt instead.

Related

Handlebars HBS Express - How to iterate an object without specify the properties

I am trying to iterate using the properties of an object to dynamically print a table having an array with the properties and an object with the values ​​of each property.
I don't know how to do the 2 iterations using hbs express from handlebars
people: [{
name: "ken",
lastname: "grace",
age: 10
},
{
name: "ron",
lastname: "bond",
age: 20
}];
properties = ["name","lastname", "age"];
HTML CODE:
<table>
<thead>
<tr>
{{#each properties as |property index|}}
<th>
<span>{{property}}</span>
</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each people}}
<tr>
{{#each properties}}
<th>
{{!-- trying something like: --}}
{{!-- {{people.property}} --}}
</th>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
As user #76484 mentioned, you want to use the built-in lookup helper:
The lookup helper allows for dynamic parameter resolution using Handlebars variables. It can be used to look up properties of object based on data from the input.
In your specific example, you'd probably want to store your people and properties iterations in a block parameter (e.g., named |person| and |property|), as well as using ../ on your inner loop since the context has changed.
Putting that all together for you example, the HBS markup might look like:
<table>
<thead>
<tr>
{{#each properties as |property index|}}
<th><span>{{property}}</span></th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each people as |person|}}
<tr>
{{#each ../properties as |property|}}
<th>{{lookup person property}}</th>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
See this playground link for the resulting HTML as well.

Using Spacebars logic in Meteor not obeying logic

I've got a template helper that returns the value of a Session, in this case it's returning in the number 1:
Template.Student.helpers({
curWeek: function () {
return Session.get('CurrentWeek').substr(0, 1);
},
My template has a table and I'm trying to print to the table a portion of it depending on the value of the helper function. So I have some logic in the template to print the right portion. But it's not obeying the logic. Even though the value of curWeek returns the value 1, the template runs the logic under {{#if curWeek 2}} as well, so both are in the table. I only want the part under {{#if curWeek 1}} to run, since that's what the value is. Am I not using the logic correctly?
<template name="Student">
{{#modalizeBody}}
<table class="bordered narrow">
<thead>
<tr>
<th>Name</th>
<th>Shift</th>
<th>Age</th>
<th>Sex</th>
<th>Level</th>
<th>Sun</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
</tr>
</thead>
<tbody>
{{#each StudsWk1Master}}
{{#if curWeek 1}}
<tr>
<td>{{FullName}}</td>
<td>{{RoomWk1}}</td>
<td>{{calculateAge Bdate}}</td>
<td>{{Sex}}</td>
<td>{{Level}}</td>
<td>{{formatName this.Teachers.Week1.Sunday}}</td>
<td>{{formatName this.Teachers.Week1.Monday}}</td>
<td>{{formatName this.Teachers.Week1.Tuesday}}</td>
<td>{{formatName this.Teachers.Week1.Wednesday}}</td>
<td>{{formatName this.Teachers.Week1.Thursday}}</td>
<td>{{formatName this.Teachers.Week1.Friday}}</td>
<td>{{formatName this.Teachers.Week1.Saturday}}</td>
</tr>
{{/if}}
{{/each}}
{{#each StudsWk1Master}}
{{#if curWeek 2}}
<tr>
<td>{{FullName}}</td>
<td>{{RoomWk2}}</td>
<td>{{calculateAge Bdate}}</td>
<td>{{Sex}}</td>
<td>{{Level}}</td>
<td>{{formatName this.Teachers.Week2.Sunday}}</td>
<td>{{formatName this.Teachers.Week2.Monday}}</td>
<td>{{formatName this.Teachers.Week2.Tuesday}}</td>
<td>{{formatName this.Teachers.Week2.Wednesday}}</td>
<td>{{formatName this.Teachers.Week2.Thursday}}</td>
<td>{{formatName this.Teachers.Week2.Friday}}</td>
<td>{{formatName this.Teachers.Week2.Saturday}}</td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
{{/modalizeBody}}
</template>
Your helper isn't testing for equality. You have:
{{#if curWeek 1}}
But your helper just returns the current week and doesn't expect a parameter.
Just add the parameter to your helper function and then return a boolean:
Template.Student.helpers({
curWeek: function (value) {
return Session.get('CurrentWeek').substr(0, 1) === value;
},

meteor spacebars nested each property by child property name

In Spacebars, can I access an outer-each’s property by name of an inner each property. I.e. ? access ymBStocks.price via via {{../{{title}}}}
More complete example
<template name="ymbStockstable">
<table class="table table-hover table-ymbStocks">
<thead>
<tr>
{{#each columns}}
<th>{{title}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each ymbStocks}}
<tr>
{{#each columns}}
<td>{{../columns.title}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
</template>
w3jimmy #w3jimmy 14:09
create a helper to get the property of an object
Template.yourTemplate.helpers({
getProperty: function (obj_name, prop_name){
if (obj_name.hasOwnProperty(prop_name)){
return obj_name.prop_name;
}
}
})
and then in spacebars you do like this:
{{#each ymbStock in ymbStocks}}
...
{{#each column in columns}}
<td>price: {{getProperty column.title ymbStock.price}}</td>
{{/each}}
{{/each}}`
I just spit it out, without testing...

When iterating with {{#each}} how to not include the entry in Meteor

The person I'm designing this app for requested that she be able to make a email list of people with birthdays within the next 7 days. One of the fields in the collection is Bdate in the format 'YYYY-MM-DD'. I decided to make a registerHelper with a simple algorithm that determines if the birthdate is one that fit the request:
Template.registerHelper('calculateBirthday', function(bdate) {
var birthDate = new Date(bdate);
var current = new Date();
var diff = current - birthDate; // Difference in milliseconds
var sevenDayDiff = Math.ceil(diff/31557600000) - (diff/31557600000);
if (sevenDayDiff <= 0.01995183087435)
return date;
else
return false;
});
The template would have a table that lists the birthdates that are the ones to get for the email list:
<table class="bordered">
<thead>
<tr>
<th>Name</th>
<th>Birthday</th>
</tr>
</thead>
<tbody>
{{#each QueryBirthday}}
<tr>
<tr>{{FullName}}</tr>
<td>{{calculateBirthday Bdate}}</td>
</tr>
{{/each}}
</tbody>
</table>
The problem with this is that it prints all the names with mostly blank birthdates. The algorithm works fine, but how to tell Meteor to only include those names and birthdates that 'should' be on the list?
The quickest way to hide unwanted items is
<table class="bordered">
<thead>
<tr>
<th>Name</th>
<th>Birthday</th>
</tr>
</thead>
<tbody>
{{#each QueryBirthday}}
{{#if calculateBirthday Bdate}}
<tr>
<td>{{FullName}}</td>
<td>{{calculateBirthday Bdate}}</td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
I don't know how your application works, but like other people who commented on your question, I would filter and send only the required results from server to client.

Auto-print the fields of a Meteor collection using helpers without specifying their name

Is it possible to auto-print the fields of a Meteor collection using helpers without specifying them?
Let's say I start having a helper that returns the collection of objects stored in a table, as follows:
{{ #each CollectionData }}
<thead>
<tr>
<th>Code</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<Tr class="object-row">
<Td> {{code}} </ td>
<Td> {{description}} </ td>
</tr>
</tbody>
...
{{/each}}
Now i specify an "object schema" for each collection to set which field i want to auto-print, pseudo example:
// Items is the name of the possible collection
Schema.items var = {
fields {
code: {
columnName: "code",
show: false,
},
description: {
columnName: "description",
show: false,
},
otherField {
columnName: "foo",
show: false,
}
}
}
Now, I would make the helper to auto-generate the table columns and values ​​of a collection field where the show check is true, without having to manually specify {{code}}, {{description}} and so on, pseudo example:
{{ #each CollectionData }}
<thead>
<tr>
{{print each column where show check is == true, without manually specifing any name}}
</tr>
</thead>
<tbody>
<Tr class="object-row">
{{print the value of the column, for this record, where show check is == true, without specifing its name}}
</tr>
</tbody>
...
{{/each}}
Is there any way to do that?
The simpliest way would be to create a template for each TD, something like
<thead>
<tr>
{{#each fetchColumnHeaders}}
{{> columnHeader }}
{{/each}}
</tr>
</thead>
{{ #each CollectionData }}
<tbody>
<Tr class="object-row">
{{#each fetchColumnItems}}
{{> columnItem}}
{{/each}}
</tr>
</tbody>
{{/each}}
<template name="columnHeader">
<th>{{label}}</th>
</template>
<template name="columnItem">
<td>{{label}}</td>
</template>
And then you can write template helpers to return the column headers, and the various items based on your schema

Resources