5

I'm trying to learn meteor and am running into a few hurdles. I have a couple nested templates to display all of the user information in my app:

users_list.html:

<template name='usersList'>
  <div class='users'>
    {{#each user}}
      {{> userItem}}
    {{/each}}
  </div>
</template>

and user_item.html:

<template name='userItem'>
  <div class='user'>
    <div class='user-content'>
      <h3>User:</h3>
        <h4>Email: {{emails}}</h4>
          <h5>ID: {{_id}}</h5>
          ...
    </div>
  </div>
</template>

and the associated template helper:

Template.usersList.helpers({
  user: function(){
    return Meteor.users.find().fetch();
  }
});

This works for top level properties, but if I try to explicitly access the .address property on the 0 index in the emails array by changing the above line in user_item.html:

<h4>Email: {{emails[0].address}}</h4>

Meteor complains:

Exception in queued task: Error: Can't call non-function: [object Object]...

This is confusing to me because I can do this in the console:

var userz = Meteor.users.find().fetch();
userz[0].emails[0].address // "[email protected]"

Any ideas on why Meteor doesn't like this?

Also, I was thinking in general that I may need to store the contents of the emails array into a variable and repeat the same pattern above except by nesting an emails_list and email_item template into the user_item template. This seems viable but overly complicated for this use case.

Ultimately, I'm really just trying to learn and implement a reasonable pattern for accessing and displaying nested attributes of documents in collections. Any thoughts or guidance will be greatly appreciated.

2 Answers 2

6

This is just a problem with your syntax, try this :

<h4>Email : {{emails.[0].address}}</h4>

You need to access the first element (a property which key is "0") of the emails array using the dot syntax.

https://github.com/meteor/meteor/wiki/Using-Blaze#dotted-helpers-with-numeric-indices

You could also use this pattern for displaying a list of emails :

(from userItem)
{{> emailsList}}

<template name="emailsList">
  <ul>
    {{#each emails}}
      {{> emailItem}}
    {{/each}}
  </ul>
</template>

<template name="emailItem">
  <li>Address : {{address}}</li>
</template>

I don't think this is overly complicated (just a couple more templates), and with Meteor this is very easy to do. Whenever reasonable, slice your templates into more subtemplates, it will simplify and speed up DOM rerendering on data invalidation.

Also, you don't need to use fetch when returning a cursor in a helper : the #each block is optimized to work directly with cursor instead of arrays. (it will be smart enough to rerender only a modified item instead of the whole list).

Sign up to request clarification or add additional context in comments.

3 Comments

This works in Meteor, thank you. This code doesn't work in the console, however. Is my javascript off today? I'm not getting why we need . notation to get at the item at the 0 index of the emails array.
This is because Spacebars (Meteor implementation of Handlebars) is something DIFFERENT from JavaScript, your syntax was OK for JS but wrong for the template engine.
@walter linked to the source of my woes. Thanks for the help
1

you can to check documentation of Blaze

For that show array in the template, you must to write like shows the documentation,

In dotted helpers, use brackets around numeric indices, eg {{currentUser.emails.[0].address}} instead of {{currentUser.emails.0.address}}

Good {{currentUser.emails.[0].address}}


Bad {{currentUser.emails.0.address}}

Wiki

https://github.com/meteor/meteor/wiki/Using-Blaze

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.