I've got a simple list of documents that are generated with the {{#each}} iterator:
{{#each Teachers}}
<td>{{FullName}}</td>
{{/each}}
When a user clicks on one of the teachers listed, a new page is routed to that teacher's profile page and we have access to that teacher's document with 'this' so I can say:
var phone = this.phoneNumber;
Now, within that teacher's profile page another list is generated of that teacher's students:
{{#each Students}}
<td>{{FullName}}</td>
{{/each}}
When the user clicks on a student in that list (on that teacher's page), I'm trying to get access to the student document by using 'this' again. So if I wrote:
Template.TeacherTemplate.events({
'click #student-name': function () {
console.log(this.FullName);
}
I'd expect to see the student's full name in the console. But it's still referencing the teacher's full name here. How can I get the reference to the student when clicking the student list?
Make another template for student.
<template name='student'>
<td>{{FullName}}</td>
</template>
Then use student template in each loop.
{{#each Students}}
{{> student}}
{{/each}}
Template.student.events({
'click': function(){
console.log(this.FullName);
}
});
Related
lets say i have this data
{
method: ['twitter','reddit','google'],
auth: {
twitter: {id: 213},
reddit: {},
}
}
i want to list all the methods that are not in auth, or are in auth but dont have an id listed
methods in auth with id:
{{#each auth}}
{{#if id}}
{{#key}}
{{/if}}
{{/each}}
methods not in auth with id:
{{#each method}}
{{#unless (lookup ../auth this)}}
{{this}}
{{/unless}}
{{/each}}
What I'm hoping to see is the first part printing out just twitter (since it's the only one that's in auth and has an id), and in the second part it should print out the opposite, both reddit and google.
Right now the second part only prints out google
My current code works for things that aren't in the auth object (google), but it's not able to check if there's an ID defined in the auth object, so it doesn't print out reddit even though it should.
I tried doing {{#unless (lookup ../auth this.id)}} but that prints out all 3, presumably because the lookup is failing.
here's a codepen: https://codepen.io/skeddles/pen/bGjzRZx
I think you are on the right track. I would just add a second lookup:
{{#each method}}
{{#unless (lookup (lookup ../auth this) 'id')}}
{{this}}
{{/unless}}
{{/each}}
This takes the result of lookup ../auth this and looks for an id property on that result. Therefore, only methods that have keys in auth that resolve to an object with id property will resolve as truthy.
I have forked your Codepen.
Following an example from a book, I have in my .js file
lists = new Mongo.Collection("Lists");
if (Meteor.isClient) {
Template.categories.helpers ({
'Category': function(){
return lists.find({}, {sort: {Category: 1}});
}})
and in my html file:
<body>
<div id="categories-container">
{{> categories}}
</div>
</body>
<template name="categories">
<div class="title">my stuff</div>
{{#each lists}}
<div>
{{Category}}
</div>
{{/each}}
</template>
I have input data this data into lists which uses Category for a field using the console:
> lists.insert({Category:"DVDs", items: {Name:"Mission Impossible"
,Owner:"me",LentTo:"Alice"}});
> lists.insert({Category:"Tools", items: {Name:"Linear Compression
Wrench",Owner:"me",LentTo: "STEVE"}});
but it doesn't output the data.
I think the issue lies in the context of your {{#each}}, you seem to be attempting to access the mongo collection itself rather specific fields through a helper function.
Check out this tutorial on spacebars, it’s a pretty good read http://meteorcapture.com/spacebars/ and also the Meteor Docs section http://docs.meteor.com/#/full/livehtmltemplates. I'm fairly new to Meteor myself but hope that helps.
In your example, you use name Category for 2 different things.
It is the name of template helper function that return an array of list items.
and it is the name of a field item inside your list.
Do the {{#each Category}} to run on the array returned by the helper
Inside the each, you should access the {{Category}} or {{item}} list items
You just need to call your helper lists instead of Category and your code will work:
Template.categories.helpers({
lists: function () {
return lists.find({}, {sort: {Category: 1}});
}
});
{{#each lists}} means: Iterate over a collection cursor (the result of a find) or an array which we get by calling the helper lists. The naming here is somewhat confusing because lists also happens to be the name of the collection your are iterating over.
Inside of the each, the context is a lists document. Each document contains a Category field, which you are outputting inside of a div.
Recommended reading:
A Guide to Meteor Templates & Data Contexts
check to run command : meteor list
it is given to you list of packages which is you used
if autopublish package not in the list you want to publish and subscribe your data here's simple example:
//in server
Meteor.publish('lists',function(){
return lists.find({}, {sort: {Category: 1}});
})
//in client
Meteor.subscribe('lists');
For More Deatails : publish subscription
First: The function in your 'categories' helper shouldn't be between quotes (not sure if that may couse problems).
Second: You are using the {{#each}} loop wrong.
You are calling the 'Lists' collection, but you should call the 'Categories' helper.
<template name="categories">
<div class="title">my stuff</div>
{{#each Category}}
<div>
{{Category}}
</div>
{{/each}}
</template>
Its very confusing your helper has the same name as the field you are calling in the #each loop.
I have an Ember 1.13 application and I want to list all users that match with another user. I have http://localhost:3000/api/v1/users/1/matches that returns
{"users":[{"id":1,"email":"test#test.com","nickname":"Test","bio":"test","created_at":"2015-06-28T16:03:52.423Z","updated_at":"2015-06-28T16:03:52.423Z","encrypted_password":"$2a$10$RPJmVJNfFvjwzIG0wfC6yONRz20WBogUw35ibz2Hv.M6TC/M7FZ8e","confirmation_token":null,"remember_token":"fb5653e22ad30d3ad3a90ab0b028bd7348cd71a1"}]}
As shown in the doc, I have this route :
export default Ember.Route.extend
model: ->
Ember.$.getJSON('http://localhost:3000/api/v1/users/1/matches')
And this template :
{{#each model as |user|}}
user
{{/each}}
I should see user in my template but I have nothing. Did I miss something?
{{#each model.users as |user|}}
user
{{/each}}
I imagine this has to be an elementary issue however I've been struggling through this for too long. I'm relatively new to Meteor.
I've viewed the documentation for the Meteor.user() (http://docs.meteor.com/#meteor_users) and can see how additional information is added to the user.profile. I.e.,
//JS file
Meteor.users.insert({
username: 'admin',
profile: {
first_name: 'Clark',
last_name: 'Kent'
},
});
How then do I display the profile information in the view template? I can access the user object via the view and web console (Meteor.user()) however I cannot access the object details.
My initial thoughts were that I could load the following in my handlebar templates but they do not work:
// HTML view
{{Meteor.user().username}}
{{Meteor.user().profile.first_name}}
{{Meteor.user().profile.last_name}}
Any help is greatly appreciated.
Your insert is correct.
But to show the information like the first name you have to provide a helper function.
Your html-template:
<template name="user">
<p>{{firstName}}</p>
</template>
Your js-code:
Template.user.helpers({
firstName: function() {
return Meteor.user().profile.first_name;
}
});
You can additionaly wrap the user template with the {{currentUser}} helper to be sure there is a user.
{{#if currentUser}}
{{> user}}
{{/if}}
If you don't want to define a proxy helper for different attributes of objects nested in {{currentUser}}, you can do the following purely in your template:
{{#with currentUser}}
{{#with profile}}
{{first_name}}
{{/with}}
{{/with}}
Updated to reflect comment suggestion.
In your templates, you'll want to use {{currentUser}} instead of {{Meteor.user()}}.
Docs
try this way
{{#with userDetails}}
First name:-{{this.first_name}}
Last name:- {{this.last_name}}
{{/with}}
//jsSide
userDetails(){
return Meteor.user();
}
What is the standard way to access outer #each collection values in the loop?
for example:
<template name="example">
{{#each outerCollection}}
<tr>
{{#each innerCollection}}
<td>{{aaa}}</td>
{{/each}}
</tr>
{{/each}}
</template>
Template.example.aaa = function(){
// cannot access outerCollection values
}
in above Template.example.aaa, this points to the inner collection.
I cannot find way to access outerCollection items.
My solution is like below, I am defining my own helper function.
Is it a standard Meteor way to achieve this purpose?
<template name="example">
{{#each outerCollection}}
<tr>
{{#each innerCollection}}
<td>{{myHelper ../outerItem innerItem}}</td>
{{/each}}
</tr>
{{/each}}
</template>
Handlebars.registerHelper('myHelper', function (outItem, inItem) {
// can access outerCollection via outerItem
});
I found a similar question for the case of inner event handler access.
I think you've answered this yourself! Using ../ is documented in https://github.com/meteor/meteor/wiki/Handlebars.
You can use below code to fetch outer collections.
suppose you have collection called as Collection.Customer and Collection.RechargePlan and you are using both in a template for updating Customer.
Customer = {"name":"James", "rechargeplan":"monthly"};
RechargePlan = [{"rechargeplan": "monthly"},{"rechargeplan": "yearly"}];
//Inside template, Bydefault Customer is available.
{{#each RechargePlan}}
{{#if equals ../rechargeplan rechargeplan}}
//Hurray Plan matches
{{/if}}
{{/each}}
In above code, ../rechargeplan is actually Customer.rechargeplan, ../ actually went one step above heirarchy and then accessed the field if available, since Customer is already available to template, it's field is picked up.