Meteor - Templating

meteor
Events

What is this 'Name data contexts to template inclusions' stuff?

It’s tempting to just provide the object you’re interested in as the entire data context of the template (like {{> Todos_item todo}}). It’s better to explicitly give it a name ({{> Todos_item todo=todo}}). There are two primary reasons for this:

  1. When using the data in the sub-component, it’s a lot clearer what you are accessing; {{todo.title}} is clearer than {{title}}.
  2. It’s more flexible, in case you need to give the component more arguments in the future.

For instance, in the case of the Todos_item sub-component, we need to provide two extra arguments to control the editing state of the item, which would have been a hassle to add if the item was used with a single todo argument.

Additionally, for better clarity, always explicitly provide a data context to an inclusion rather than letting it inherit the context of the template where it was rendered:

<!-- bad: inherits data context, who knows what is in there! -->
{{> myTemplate}}

<!-- explicitly passes empty data context -->
{{> myTemplate ""}}

Why should we prefer to use {{#each .. in}}?

For similar reasons to the above, it’s better to use {{#each todo in todos}} rather than the older {{#each todos}}. The second sets the entire data context of its children to a single todo object, and makes it difficult to access any context from outside of the block.

The only reason not to use {{#each .. in}} would be because it makes it difficult to access the todo symbol inside event handlers. Typically the solution to this is to use a sub-component to render the inside of the loop:

{{#each todo in todos}}
  {{> Todos_item todo=todo}}
{{/each}}

Now you can access this.todo inside Todos_item event handlers and helpers.

How can we pass data to helpers?

Rather than accessing data in helpers via this, it’s better to pass the arguments in directly from the template. So our checkedClass helper takes the todo as an argument and inspects it directly, rather than implicitly using this.todo. We do this for similar reasons to why we always pass arguments to template inclusions, and because “template variables” (such as the iteratee of the {{#each .. in}} helper) are not available on this.

How can we output the result of a template helper if it returns string?

If we have a helper function defined:

Template.templateName.helpers({
  helperName: function() {
    return "Hello world!";
  }
});

we can output the result of this helper:

{{helperName}}

How can we define a template helper using the new way?

Template.templateName.helpers({
  helperName: function() {
    return "Hello world!";
  }
});

How can we define a template helper using the old way?

Template.templateName.helperName = function(){
    return "Some other text";
}

How can we use the template instance?

Although Blaze’s simple API doesn’t necessarily encourage a componentized approach, you can use the template instance as a convenient place to store internal functionality and state. The template instance can be accessed via this inside Blaze’s lifecycle callbacks and as Template.instance() in event handlers and helpers. It’s also passed as the second argument to event handlers.

We suggest a convention of naming it instance in these contexts and assigning it at the top of every relevant helper. For instance:

Template.Lists_show.helpers({
  todoArgs(todo) {
    const instance = Template.instance();
    return {
      todo,
      editing: instance.state.equals('editingTodo', todo._id),
      onEditingChange(editing) {
        instance.state.set('editingTodo', editing ? todo._id : false);
      }
    };
  }
});

Template.Lists_show.events({
  'click .js-cancel'(event, instance) {
    instance.state.set('editingTodo', false);
  }
});

What are the four major types of template tags?

There are four major types of template tags:

  1. {{ }} - Double-braced template tags are used to insert a string of text. The text is automatically made safe. It may contain any characters (like <) and will never produce HTML tags.
  2. {{> templateName}} or {{> templateName dataObject}}- Inclusion template tags are used to insert another template by name.
  3. {{#each}} - Block template tags are notable for having a block of content. The block tags #if, #each, #with, and #unless are built in, and it is also possible define custom ones. Some block tags, like #each and #with, establish a new data context for evaluating their contents. In the above example, {{title}} and {{content}} most likely refer to properties of the current post (though they could also refer to template helpers).
  4. {{{content}}} - Triple-braced template tags are used to insert raw HTML. Be careful with these! It’s your job to make sure the HTML is safe, either by generating it yourself or sanitizing it if it came from a user input.

How can we add logic and data to our templates?

All of the code in your HTML files is compiled with Meteor's Spacebars compiler. Spacebars uses statements surrounded by double curly braces such as {{#each}} and {{#if}} to let you add logic to your views.

How can we pass data into our templates so that the template can render the data?

We can pass data into our templates by defining helpers. In the todos example application, we defined a helper called tasks on Template.body that returns an array. Inside the body tag of the HTML, we can use #each tasks to iterate over the array and insert a task template for each value. Inside the #each block, we can display the text property of each array item using text.

How can we use Jade with Blaze?

If you don’t like the Spacebars syntax Meteor uses by default and want something more concise, you can give Jade a try by using dalgard:jade. This package will compile all files in your app with the .jade extension into Blaze-compatible code, and can be used side-by-side with blaze-html-templates if you want to have some of your code in Spacebars and some in Jade.

How can we use React with Meteor?

If you’re building your app’s UI with React, currently the most popular way to write your UI components involves JSX, an extension to JavaScript that allows you to type HTML tags that are converted to React DOM elements. JSX code is handled automatically by the ecmascript package.

If you want to use React but don’t want to deal with JSX and prefer a more HTML-like syntax, there are a few community options available. One that stands out in particular is Blaze-React, which simulates the entire Blaze API using React as a rendering engine.

How can we use Angular with Meteor?

If you would like to write your UI in Angular, you will need to switch out Meteor’s Blaze template compiler which comes by default with the Angular one. Read about how to do this in the Angular-Meteor tutorial.

What is Blaze?

Blaze is Meteor’s built-in reactive rendering library. Usually, templates are written in Spacebars, a variant of Handlebars designed to take advantage of Tracker, Meteor’s reactivity system. These templates are compiled into JavaScript UI components that are rendered by the Blaze library.

Blaze is not required to build applications in Meteor—you can also easily use React or Angular to develop your UI (here’s a comparison). However, this particular article will take you through best practices in building an application in Blaze, which is used as the UI engine in all of the other articles.

Can we pass parameters to a template?

Yes. We can do it by defining a helper function, and using it with the #each construct. We can also do:

{{>subscriber name='topics' count=5}}

How can we access Blaze template helper function directly?

I don't believe this is possible with current versions of Blaze. That being said, you can simulate this by declaring a single global Template helper function, like:

Template.registerHelper('instance', function () {
  return Template.instance();
});

The above code define a global helper named 'instance'. This helper function returns the result of Template.instance() which is probably the current template. Just define this once in a common client location, and you can then reference instance in any of your Template's. So you could reference your test variable like:

{{instance.test}}

http://stackoverflow.com/questions/39037734/meteor-how-to-access-templates-instance-key-in-blaze-directly-without-helper

What are the restrictions on the name of the template?

Template name cannot contain hyphens and other special characters.

What is a template instance?

The same template may occur many times on a page, and these occurrences are called template instances.

What is the lifecycle of each template instance?

Template instances have a life cycle of being created, put into the document, and later taken out of the document and destroyed. Meteor manages these stages for you, including determining when a template instance has been removed or replaced and should be cleaned up.

How can we define a template helper?

Template.myTemplate.helpers({
  foo() {
    return Session.get("foo");
  }
});

Now you can invoke this helper with foo in the template defined with <template name="myTemplate">.

How can we define a template helper with parameters?

Helpers can accept positional and keyword arguments:

Template.myTemplate.helpers({
  displayName(firstName, lastName, keyword) {
    var prefix = keyword.hash.title ? keyword.hash.title + " " : "";
    return prefix + firstName + " " + lastName;
  }
});

Then you can call this helper from template like this:

{{displayName "John" "Doe" title="President"}}

What is the relationship between a template helper and Tracker.autorun?

Under the hood, each helper starts a new Tracker.autorun. When its reactive dependencies change, the helper is rerun. Helpers depend on their data context, passed arguments and other reactive data sources accessed during execution.

How can we create a helper that can be used in any template?

To create a helper that can be used in any template, use Template.registerHelper.

What is the purpose of onRender callback?

Callbacks added with this method are called once when an instance of Template.myTemplate is rendered into DOM nodes and put into the document for the first time. In the body of a callback, this is a template instance object that is unique to this occurrence of the template and persists across re-renderings. Use the onCreated and onDestroyed callbacks to perform initialization or clean-up on the object. Because your template has been rendered, you can use functions like this.findAll which look at its DOM nodes. This can be a good place to apply any DOM manipulations you want, after the template is rendered for the first time.

<template name="myPictures">
  <div class="container">
    {{#each pictures}}
      <img class="item" src="/{{.}}"/>
    {{/each}}
  </div>
</template>
Template.myPictures.onRendered(function () {
  // Use the Packery jQuery plugin
  this.$('.container').packery({
    itemSelector: '.item',
    gutter: 10
  });
});

What is the purpose of onCreated callback?

Callbacks added with this method are called before your template’s logic is evaluated for the first time. Inside a callback, this is the new template instance object. Properties you set on this object will be visible from the callbacks added with onRendered and onDestroyed methods and from event handlers.

These callbacks fire once and are the first group of callbacks to fire. Handling the created event is a useful way to set up values on template instance that are read from template helpers using Template.instance().

Template.myPictures.onCreated(function () {
  // set up local reactive variables
  this.highlightedPicture = new ReactiveVar(null);
  // register this template within some central store
  GalleryTemplates.push(this);
});

What is the purpose of onDestroy callback?

Register a function to be called when an instance of this template is removed from the DOM and destroyed. These callbacks are called when an occurrence of a template is taken off the page for any reason and not replaced with a re-rendering. Inside a callback, this is the template instance object being destroyed. This group of callbacks is most useful for cleaning up or undoing any external effects of created or rendered groups. This group fires once and is the last callback to fire.

Template.myPictures.onDestroyed(function () {
  // deregister from some central store
  GalleryTemplates = _.without(GalleryTemplates, this);
});

How can we access the current template instance from inside a helper?

You can access the current template instance from helpers using Template.instance().

Why can we only access findAll, find, firstNode, and lastNode from the onRendered callback?

You can only access findAll, find, firstNode, and lastNode from the onRendered callback and event handlers, not from onCreated and onDestroyed, because they require the template instance to be in the DOM.

How can we determine the type of a particular template instance?

Use the JavaScript instanceof operator:

instanceof Blaze.TemplateInstance

What is the purpose of the findAll template method?

Find all elements matching selector in this template instance, where selector is the CSS selector to match, scoped to the template contents. Returns an array of DOM elements matching selector.

What is the purpose of the $ template method?

Find all elements matching selector in this template instance, and return them as a JQuery object. Returns a jQuery object of those same elements. jQuery objects are similar to arrays, with additional methods defined by the jQuery library. The template instance serves as the document root for the selector. Only elements inside the template and its sub-templates can match parts of the selector.

What is the purpose of the find template method?

Find one element matching selector in this template instance. Returns one DOM element matching selector, or null if there are no such elements.

What is the purpose of the firstNode template method?

The first top-level DOM node in this template instance. The two nodes firstNode and lastNode indicate the extent of the rendered template in the DOM. The rendered template includes these nodes, their intervening siblings, and their descendents. These two nodes are siblings (they have the same parent), and lastNode comes after firstNode, or else they are the same node.

What is the purpose of the lastNode template method?

The last top-level DOM node in this template instance.

How can we get the data context for a particular template instance?

Use the data template method. This property provides access to the data context at the top level of the template. It is updated each time the template is re-rendered. Access is read-only and non-reactive.

What is the purpose of the autorun template method?

A version of Tracker.autorun that is stopped when the template is destroyed. The function to run. It receives one argument: a Tracker.Computation object. You can use this.autorun from an onCreated or onRendered callback to reactively update the DOM or the template instance. You can use Template.currentData() inside of this callback to access reactive data context of the template instance. The Computation is automatically stopped when the template is destroyed.

This is an alias for template.view.autorun.

What is the purpose of the subscribe template method?

A version of Meteor.subscribe that is stopped when the template is destroyed. Signature:

Blaze.TemplateInstance.subscribe(name, [arg1, arg2...], [options])
  1. name (String): Name of the subscription. Matches the name of the server's publish() call.
  2. arg1, arg2, .. (Any): Optional arguments passed to publisher function on server.

Options:

  1. onReady (Function): Passed to Meteor.subscribe.
  2. onStop (Function): Passed to Meteor.subscribe.
  3. connection (DDP connection): The connection on which to make the subscription.

You can use this.subscribe from an onCreated callback to specify which data publications this template depends on. The subscription is automatically stopped when the template is destroyed.

What is the purpose of subscriptionsReady?

There is a complementary function Template.instance().subscriptionsReady() which returns true when all of the subscriptions called with this.subscribe are ready.

Inside the template’s HTML, you can use the built-in helper Template.subscriptionsReady, which is an easy pattern for showing loading indicators in your templates when they depend on data loaded from subscriptions.

Template.notifications.onCreated(function () {
  // Use this.subscribe inside onCreated callback
  this.subscribe("notifications");
});

<template name="notifications">
  {{#if Template.subscriptionsReady}}
    <!-- This is displayed when all data is ready. -->
    {{#each notifications}}
      {{> notification}}
    {{/each}}
  {{else}}
    Loading...
  {{/if}}
</template>

Template.comments.onCreated(function () {
  // Use this.subscribe with the data context reactively
  this.autorun(() => {
    var dataContext = Template.currentData();
    this.subscribe("comments", dataContext.postId);
  });
});

{{#with post}}
  {{> comments postId=_id}}
{{/with}}

Template.listing.onRendered(function () {
  var template = this;
  template.subscribe('listOfThings', () => {
    // Wait for the data to load using the callback
    Tracker.afterFlush(() => {
      // Use Tracker.afterFlush to wait for the UI to re-render
      // then use highlight.js to highlight a code snippet
      highlightBlock(template.find('.code'));
    });
  });
});

What is the purpose of Template.instance()?

The template instance corresponding to the current template helper, event handler, callback, or autorun. If there isn't one, null.

What is the purpose of currentData() template method?

  1. Inside an onCreated, onRendered, or onDestroyed callback, returns the data context of the template.
  2. Inside an event handler, returns the data context of the template on which this event handler was defined.
  3. Inside a helper, returns the data context of the DOM node where the helper was used.

Establishes a reactive dependency on the result.

What is the purpose of parentData() template method?

Accesses other data contexts that enclose the current data context. Signature:

Template.parentData([numLevels])

Arguments:

  1. numLevels: The number of levels beyond the current data context to look. Defaults to 1.

For example, Template.parentData(0) is equivalent to Template.currentData(). Template.parentData(2) is equivalent to {{../..}} in a template.

What is the purpose of Template.body?

The template object representing your <body> tag. You can define helpers and event maps on Template.body just like on any Template.myTemplate object.

Helpers on Template.body are only available in the <body> tags of your app. To register a global helper, use Template.registerHelper. Event maps on Template.body don’t apply to elements added to the body via Blaze.render, jQuery, or the DOM API, or to the body element itself. To handle events on the body, window, or document, use jQuery or the DOM API.

What is the purpose of Template.dynamic?

Choose a template to include dynamically, by name.

{{> Template.dynamic template=template [data=data] }}

Arguments:

  1. template (String): The name of the template to include.
  2. data (Object): Optional. The data context in which to include the template.

Template.dynamic allows you to include a template by name, where the name may be calculated by a helper and may change reactively. The data argument is optional, and if it is omitted, the current data context is used. It’s also possible, to use Template.dynamic as a block helper ({{#Template.dynamic}} ... {{/Template.dynamic}})

For example, if there is a template named “foo”, {{> Template.dynamic template="foo"}} is equivalent to {{> foo}} and {{#Template.dynamic template="foo"}} ... {{/Template.dynamic}} is equivalent to {{#foo}} ... {{/foo}}.

How can we define an event handler?

Template.templateName.events({
  // Fires when any element is clicked
  'click'(event, instance) { ... },
  // Fires when any element with the 'accept' class is clicked
  'click .accept'(event,instance) { ... },
  // Fires when 'accept' is clicked or focused, or a key is pressed
  'click .accept, focus .accept, keypress'(event, instance) { ... }
});

The handler function receives two arguments:

  1. event: an object with information about the event
  2. template: a template instance for the template where the handler is defined.

The handler also receives some additional context data in this, depending on the context of the current element handling the event. In a template, an element’s context is the data context where that element occurs, which is set by block helpers such as #with and #each.

Most events bubble up the document tree from their originating element. For example, 'click p' catches a click anywhere in a paragraph, even if the click originated on a link, span, or some other element inside the paragraph. The originating element of the event is available as the target property, while the element that matched the selector and is currently handling it is called currentTarget.

{
  'click p'(event) {
    var paragraph = event.currentTarget; // always a P
    var clickedElement = event.target; // could be the P or a child element
  }
}

If a selector matches multiple elements that an event bubbles to, it will be called multiple times, for example in the case of 'click div' or 'click *'. If no selector is given, the handler will only be called once, on the original target element.

The following properties and methods are available on the event object passed to handlers:

  1. type (String): The event’s type, such as “click”, “blur” or “keypress”.
  2. target (DOM element): The element that originated the event.
  3. currentTarget (DOM element): The element currently handling the event. This is the element that matched the selector in the event map. For events that bubble, it may be target or an ancestor of target, and its value changes as the event bubbles.
  4. which (Number): For mouse events, the number of the mouse button (1=left, 2=middle, 3=right). For key events, a character or key code.
  5. stopPropagation(): Prevent the event from propagating (bubbling) up to other elements. Other event handlers matching the same element are still fired, in this and other event maps.
  6. stopImmediatePropagation(): Prevent all additional event handlers from being run on this event, including other handlers in this event map, handlers reached by bubbling, and handlers in other event maps.
  7. preventDefault(): Prevents the action the browser would normally take in response to this event, such as following a link or submitting a form. Further handlers are still called, but cannot reverse the effect.
  8. isPropagationStopped(): Returns whether stopPropagation() has been called for this event.
  9. isImmediatePropagationStopped(): Returns whether stopImmediatePropagation() has been called for this event.
  10. isDefaultPrevented(): Returns whether preventDefault() has been called for this event.

Returning false from a handler is the same as calling both stopImmediatePropagation and preventDefault on the event.

Event types and their uses include:

  1. click: Mouse click on any element, including a link, button, form control, or div. Use preventDefault() to prevent a clicked link from being followed. Some ways of activating an element from the keyboard also fire click.
  2. dblclick: Double-click.
  3. focus, blur: A text input field or other form control gains or loses focus. You can make any element focusable by giving it a tabindex property. Browsers differ on whether links, checkboxes, and radio buttons are natively focusable. These events do not bubble.
  4. change: A checkbox or radio button changes state. For text fields, use blur or key events to respond to changes.
  5. mouseenter, mouseleave: The pointer enters or leaves the bounds of an element. These events do not bubble.
  6. mousedown, mouseup: The mouse button is newly down or up.
  7. keydown, keypress, keyup: The user presses a keyboard key. keypress is most useful for catching typing in text fields, while keydown and keyup can be used for arrow keys or modifier keys.

Other DOM events are available as well, but for the events above, Meteor has taken some care to ensure that they work uniformly in all browsers.

How can we create a template?

<template name="myPage">
  <h1>{{pageTitle}}</h1>
  {{> nav}}
  {{#each posts}}
    <div class="post">
      <h3>{{title}}</h3>
      <div class="post-content">
        {{{content}}}
      </div>
    </div>
  {{/each}}
</template>

How does Spacebar interpret the arguments for inclusion tags or block tags?

Inclusion tags ({{> foo}}) and block tags ({{#foo}}) take a single data argument, or no argument. Any other form of arguments will be interpreted as an object specification or a nested helper:

  1. Object specification: If there are only keyword arguments, as in {{#with x=1 y=2}} or {{> prettyBox color=red}}, the keyword arguments will be assembled into a data object with properties named after the keywords.
  2. Nested Helper: If there is a positional argument followed by other (positional or keyword arguments), the first argument is called on the others using the normal helper argument calling convention.

What are the limitations with template tag replacement?

Unlike purely string-based template systems, Spacebars is HTML-aware and designed to update the DOM automatically. As a result, you can’t use a template tag to insert strings of HTML that don’t stand on their own, such as a lone HTML start tag or end tag, or that can’t be easily modified, such as the name of an HTML element.

There are three main locations in the HTML where template tags are allowed:

  1. At element level (i.e. anywhere an HTML tag could go)
  2. In an attribute value
  3. In a start tag in place of an attribute name/value pair

The behavior of a template tag is affected by where it is located in the HTML, and not all tags are allowed at all locations.

How does Spacebars evaluate double-brace tags?

A double-braced tag at element level or in an attribute value typically evalutes to a string. If it evalutes to something else, the value will be cast to a string, unless the value is null, undefined, or false, which results in nothing being displayed.

Values returned from helpers must be pure text, not HTML. (That is, strings should have <, not &lt;.) Spacebars will perform any necessary escaping if a template is rendered to HTML.

What is the purpose of the inclusion tags?

An inclusion tag takes the form {{> templateName}} or {{> templateName dataObj}}. Other argument forms are syntactic sugar for constructing a data object (see Inclusion and Block Arguments).

An inclusion tag inserts an instantiation of the given template at the current location. If there is an argument, it becomes the data context, much as if the following code were used:

{{#with dataObj}}
  {{> templateName}}
{{/with}}

Instead of simply naming a template, an inclusion tag can also specify a path that evalutes to a template object, or to a function that returns a template object.

Note that the above two points interact in a way that can be surprising! If foo is a template helper function that returns another template, then {{>foo bar}} will first push bar onto the data context stack then call foo(), due to the way this line is expanded as shown above. You will need to use Template.parentData(1) to access the original context. This differs from regular helper calls like {{foo bar}}, in which bar is passed as a parameter rather than pushed onto the data context stack.

What happens when a template inclusion tag resolves to a function?

If an inclusion tag resolves to a function, the function must return a template object or null. The function is reactively re-run, and if its return value changes, the template will be replaced.

What is the purpose of block template tags?

Block tags invoke built-in directives or custom block helpers, passing a block of template content that may be instantiated once, more than once, or not at all by the directive or helper.

{{#block}}
  <p>Hello</p>
{{/block}}

Block tags may also specify “else” content, separated from the main content by the special template tag {{else}}. A block tag’s content must consist of HTML with balanced tags. Block tags can be used inside attribute values:

<div class="{{#if done}}done{{else}}notdone{{/if}}">
  ...
</div>

How does Spacebar handle if/unless template tag?

An #if template tag renders either its main content or its “else” content, depending on the value of its data argument. Any falsy JavaScript value (including null, undefined, 0, "", and false) is considered false, as well as the empty array, while any other value is considered true.

{{#if something}}
  <p>It's true</p>
{{else}}
  <p>It's false</p>
{{/if}}

#unless is just #if with the condition inverted.

What is the purpose of the #with template tag?

A #with template tag establishes a new data context object for its contents. The properties of the data context object are where Spacebars looks when resolving template tag names.

{{#with employee}}
  <div>Name: {{name}}</div>
  <div>Age: {{age}}</div>
{{/with}}

We can take advantage of the object specification form of a block tag to define an object with properties we name:

{{#with x=1 y=2}}
  {{{getHTMLForPoint this}}}
{{/with}}

If the argument to #with is falsy (by the same rules as for #if), the content is not rendered. An “else” block may be provided, which will be rendered instead. If the argument to #with is a string or other non-object value, it may be promoted to a JavaScript wrapper object (also known as a boxed value) when passed to helpers, because JavaScript traditionally only allows an object for this. Use String(this) to get an unboxed string value or Number(this) to get an unboxed number value.

What is the purpose of the #each template tag?

An #each template tag takes a sequence argument and inserts its content for each item in the sequence, setting the data context to the value of that item:

<ul>
{{#each people}}
  <li>{{name}}</li>
{{/each}}
</ul>

The newer variant of #each doesn’t change the data context but introduces a new variable that can be used in the body to refer to the current item:

<ul>
{{#each person in people}}
  <li>{{person.name}}</li>
{{/each}}
</ul>

The argument is typically a Meteor cursor (the result of collection.find(), for example), but it may also be a plain JavaScript array, null, or undefined. An “else” section may be provided, which is used (with no new data context) if there are zero items in the sequence at any time. You can use a special variable @index in the body of #each to get the 0-based index of the currently rendered value in the sequence.

What is the reactivity model for the each template tag?

When the argument to #each changes, the DOM is always updated to reflect the new sequence, but it’s sometimes significant exactly how that is achieved. When the argument is a Meteor live cursor, the #each has access to fine-grained updates to the sequence – add, remove, move, and change callbacks – and the items are all documents identified by unique ids. As long as the cursor itself remains constant (i.e. the query doesn’t change), it is very easy to reason about how the DOM will be updated as the contents of the cursor change. The rendered content for each document persists as long as the document is in the cursor, and when documents are re-ordered, the DOM is re-ordered.

Things are more complicated if the argument to the #each reactively changes between different cursor objects, or between arrays of plain JavaScript objects that may not be identified clearly. The implementation of #each tries to be intelligent without doing too much expensive work. Specifically, it tries to identify items between the old and new array or cursor with the following strategy:

  1. For objects with an _id field, use that field as the identification key
  2. For objects with no _id field, use the array index as the identification key. In this case, appends are fast but prepends are slower.
  3. For numbers or strings, use their value as the identification key.

In case of duplicate identification keys, all duplicates after the first are replaced with random ones. Using objects with unique _id fields is the way to get full control over the identity of rendered elements.

What is the purpose of the let template tag?

The #let tag creates a new alias variable for a given expression. While it doesn’t change the data context, it allows to refer to an expression (helper, data context, another variable) with a short-hand within the template:

{{#let name=person.bio.firstName color=generateColor}}
  <div>{{name}} gets a {{color}} card!</div>
{{/let}}

Variables introduced this way take precedence over names of templates, global helpers, fields of the current data context and previously introduced variables with the same name.

What is a custom block helper?

To define your own block helper, simply declare a template, and then invoke it using {{#someTemplate}} (block) instead of {{> someTemplate}} (inclusion) syntax.

When a template is invoked as a block helper, it can use {{> Template.contentBlock}} and {{> Template.elseBlock}} to include the block content it was passed. Here is a simple block helper that wraps its content in a div:

<template name="note">
  <div class="note">
    {{> Template.contentBlock}}
  </div>
</template>

You would invoke it as:

{{#note}}
  Any content here
{{/note}}

Here is an example of implementing #unless in terms of #if (ignoring for the moment that unless is a built-in directive):

<template name="unless">
  {{#if this}}
    {{> Template.elseBlock}}
  {{else}}
    {{> Template.contentBlock}}
  {{/if}}
</template>

Note that the argument to #unless (the condition) becomes the data context in the unless template and is accessed via this. However, it would not work very well if this data context was visible to Template.contentBlock, which is supplied by the user of unless.

Therefore, when you include {{> Template.contentBlock}}, Spacebars hides the data context of the calling template, and any data contexts established in the template by #each and #with. They are not visible to the content block, even via … Put another way, it’s as if the {{> Template.contentBlock}} inclusion occurred at the location where #unless was invoked, as far as the data context stack is concerned.

You can pass an argument to {{> Template.contentBlock}} or {{> Template.elseBlock}} to invoke it with a data context of your choice. You can also use #if Template.contentBlock to see if the current template was invoked as a block helper rather than an inclusion.

What is a comment tag?

Comment template tags begin with {{! and can contain any characters except for }}. Comments are removed upon compilation and never appear in the compiled template code or the generated HTML.

{{! Start of a section}}
<div class="section">
  ...
</div>

Comment tags also come in a “block comment” form. Block comments may contain {{ and }}:

{{!-- This is a block comment.
We can write {{foo}} and it doesn't matter.
{{#with x}}This code is commented out.{{/with}}
--}}

What is a nested sub-expression?

Sometimes an argument to a helper call is best expressed as a return value of some other expression. For this and other cases, one can use parentheses to express the evaluation order of nested expressions.

{{capitalize (getSummary post)}}

In this example, the result of the getSummary helper call will be passed to the capitalize helper. Sub-expressions can be used to calculate key-word arguments, too:

{{> tmpl arg=(helper post)}}

How can we escape curly braces?

To insert a literal {{, {{{, or any number of curly braces, put a vertical bar after it. So {{| will show up as {{, {{{| will show up as {{{, and so on.

How can we evaluate a template into a String in JavaScript?

Use Blaze.toHTML:

var help = Blaze.toHTML(Template.helpModal)

What is the template engine used by Meteor?

Spacebars — a Handlebars-inspired syntax.

<head>
  <title>Your Cool Meteor App</title>
</head>
<body>
  {{> myCoolTemplate}}
</body>

<template name="myCoolTemplate">
  <p>Hello world.</p>
</template>

This is a basic interface for a Meteor application with a template included between the body tags. Notice that:

  • We haven’t included the html tags.
  • We haven’t included any CSS files.
  • We haven’t included any JavaScript files.

That’s because we don’t need to do these things since Meteor takes care of them for us.

Meteor has it’s own templating system called Spacebars. It’s basically Handlebars, but built to minimize DOM manipulations to keep things speedy (kind of like Facebook’s React).

Do we have to pre-compile our templates?

No need to worry about compiling the templates. Just create html files and code away - Meteor collects them up just like it does with your Javascript and CSS - it just works straight off the bat.

How can we define and use a template?

The default main.html file contains:

<head>
  <title>grill</title>
</head>

<body>
  <h1>Welcome to Meteor!</h1>

  {{> hello}}
  {{> info}}
</body>

<template name="hello">
  <button>Click Me</button>
  <p>You've pressed the button {{counter}} times.</p>
</template>

<template name="info">
  <h2>Learn Meteor!</h2>
  <ul>
    <li><a href="https://www.meteor.com/try" target="_blank">Do the Tutorial</a></li>
    <li><a href="http://guide.meteor.com" target="_blank">Follow the Guide</a></li>
    <li><a href="https://docs.meteor.com" target="_blank">Read the Docs</a></li>
    <li><a href="https://forums.meteor.com" target="_blank">Discussions</a></li>
  </ul>
</template>

It defines 2 templates (hello and info) and use them. Here is another example:

<body>
  <div class="container">
    <header>
      <h1>Todo List</h1>
    </header>
    <ul>
      {{#each tasks}}
        {{> task}}
      {{/each}}
    </ul>
  </div>
</body>

<template name="task">
  <li>{{text}}</li>
</template>

In the above example, tasks is an array of data, and #each is used to iterate over each element of this array, and for each element, it execute the template named "task".

How does Meteor parse the HTML file?

Meteor parses HTML files and identifies three top-level tags: <head>, <body>, and <template>. Everything inside any <head> tags is added to the head section of the HTML sent to the client, and everything inside <body> tags is added to the body section, just like in a regular HTML file.

Everything inside <template> tags is compiled into Meteor templates, which can be included inside HTML with > templateName or referenced in your JavaScript with Template.templateName.

The body section can be referenced in your JavaScript with Template.body. Think of it as a special "parent" template, that can include the other child templates.

How can we add logic and data to templates?

All of the code in your HTML files is compiled with Meteor's Spacebars compiler. Spacebars uses statements surrounded by double curly braces such as #each and #if to let you add logic and data to your views.

<body>
  <div class="container">
    <header>
      <h1>Todo List</h1>
    </header>

     <ul>
      {{#each tasks}}
        {{> task}}
      {{/each}}
    </ul>
  </div>

</body>

<template name="task">
  <li>{{text}}</li>
</template>
import { Template } from 'meteor/templating';
import './body.html';

Template.body.helpers({
  tasks: [
    { text: 'This is task 1' },
    { text: 'This is task 2' },
    { text: 'This is task 3' },
  ],
});

You can pass data into templates from your JavaScript code by defining helpers. In the code above, we defined a helper called tasks on Template.body that returns an array. Inside the body tag of the HTML, we can use #each tasks to iterate over the array and insert a task template for each value. Inside the #each block, we can display the text property of each array item using text.

How can we add a form?

Insert the code blow to our existing html:

      <form class="new-task">
        <input type="text" name="text" placeholder="Type to add new tasks" />
      </form>

Here's the JavaScript code we need to add to listen to the submit event on the form:

Template.body.events({
  'submit .new-task'(event) {

    // Prevent default browser form submit
    event.preventDefault();

    // Get value from form element
    const target = event.target;
    const text = target.text.value;

     // Insert a task into the collection
    Tasks.insert({
      text,
      createdAt: new Date(), // current time
    });

    // Clear form
    target.text.value = '';
  },
});

Now your app has a new input field. To add a task, just type into the input field and hit enter. If you open a new browser window and open the app again, you'll see that the list is automatically synchronized between all clients.

Event listeners are added to templates in much the same way as helpers are: by calling Template.templateName.events(…) with a dictionary. The keys describe the event to listen for, and the values are event handlers that are called when the event happens.

In our case above, we are listening to the submit event on any element that matches the CSS selector .new-task. When this event is triggered by the user pressing enter inside the input field, our event handler function is called.

The event handler gets an argument called event that has some information about the event that was triggered. In this case event.target is our form element, and we can get the value of our input with event.target.text.value. You can see all of the other properties of the event object by adding a console.log(event) and inspecting the object in your browser console.

In the last line of the event handler, we clear the input to prepare for another new task.

Inside the event handler, we are adding a task to the tasks collection by calling Tasks.insert(). We can assign any properties to the task object, such as the time created, since we don't ever have to define a schema for the collection.

How can we implement a template helper?

Template.task.helpers({
  isOwner() {
    return this.owner === Meteor.userId();
  },
});

How can we execute a helper function?

The old way to define a helper:

Template.leaderboard.player = function(){
    return "Some other text";
}
{{player}}

Because of this, the text being returned by the function will appear inside the browser. If the text doesn’t appear, fear not. This approach to creating helper functions might have been removed from Meteor, but now that we’ve talked about the old way of creating helper functions, we’re ready to talk about the new way.

Template.leaderboard.helpers({
    'player': function(){
        return "Some other text";
    }
});

By using commas, we can create multiple helper functions inside a single block of code:

Template.leaderboard.helpers({
    'player': function(){
        return "Some other text";
    },
    'otherHelperFunction': function(){
        return "Some other function";
    }
});

We can then reference these helper functions from inside the template:

{{player}}
{{otherHelperFunction}}

How can we use the each construct to loop over the result of a helper function?

Template.leaderboard.helpers({
    'player': function(){
        return PlayersList.find();
    }
});
{{#each player}}
    test
{{/each}}

In the above code, we execute the helper function and pass the result to the each loop. Because there are six players in the collection, the word “test” appears six times.

Within the each block, we can also retrieve the value of the fields from inside the documents. So because we’re retrieving data from the “PlayersList” collection, we can show the values of the “name” and “score” fields that are associated with each player.

To display the player’s names, for instance, refer to the “name” field from inside the each block, wrapping the field name in a double-curly braces:

{{#each player}}
    {{name}}
{{/each}}

Then, to display the player’s scores, do the same for the “score” field:

{{#each player}}
    {{name}}: {{score}}
{{/each}}

But this information will be easier to read as a list, so use the ul and li tags to achieve this:

<ul>
    {{#each player}}
        <li>{{name}}: {{score}}</li>
    {{/each}}
</ul>

How should we implement event handling?

<li class="player">{{name}}: {{score}}</li>
Template.leaderboard.events({
    'click .player': function(){
        console.log("You clicked something");
    }
});

What happens when a helper is executed inside an each block?

It get access to the individual item that the each loop currently working on through the this keyword.

Template.leaderboard.helpers({
    'player': function(){
        return PlayersList.find();
    },
    'selectedClass': function(){
      var playerId = this._id;
      var selectedPlayer = Session.get('selectedPlayer');
      if(playerId == selectedPlayer){
          return "selected"
      }
    }
});
<ul>
    {{#each player}}
        <li class="player {{selectedClass}}">{{name}}: {{score}}</li>
    {{/each}}
</ul>

Because the “selectedClass” function is being executed from inside the each block, it has access to all of the data associated with each document, including the name field, the score field, and the _id field.

What is a template helper?

Additionally we can see an example of a template helper—checkedClass todo calls out to a checkedClass helper defined in a separate JavaScript file. The HTML template and JavaScript file together define the Todos_item component:

Template.Todos_item.helpers({
  checkedClass(todo) {
    return todo.checked && 'checked';
  }
});

In the context of a Blaze helper, this is scoped to the current data context at the point the helper was used. This can be hard to reason about, so it’s often a good idea to instead pass the required data into the helper as an argument (as we do here).

What is the behavior of the each template helper?

{{#each todo in todos}}
  {{> Todos_item (todoArgs todo)}}
{{else}}
  <div class="wrapper-message">
    <div class="title-message">No tasks here</div>
    <div class="subtitle-message">Add new tasks using the field above</div>
  </div>
{{/each}}
  1. The #each .. in block helper which repeats a block of HTML for each element in an array or cursor, or renders the contents of the {{else}} block if no items exist.
  2. The template inclusion tag, {{> Todos_item (todoArgs todo)}} which renders the Todos_item component with the data context returned from the todosArg helper.

How can we call helpers with arguments?

You can provide arguments to a helper like checkedClass by simply placing the argument after the helper call, as in: checkedClass todo true "checked". You can also provide a list of named keyword arguments to a helper with checkedClass todo noClass=true classname="checked". When you pass keyword arguments, you need to read them off of the hash property of the final argument. Here’s how it would look for the example we just saw:

Template.Todos_item.helpers({
  checkedClass(todo, options) {
    const classname = options.hash.classname || 'checked';
    if (todo.checked) {
      return classname;
    } else if (options.hash.noClass) {
      return `no-${classname}`;
    }
  }
});

Note that using keyword arguments to helpers is a little awkward, so in general it’s usually easier to avoid them. This feature was included for historical reasons to match the way keyword arguments work in Handlebars.

You can also pass the output of a helper to a template inclusion or other helper. To do so, use parentheses to show precedence:

{{> Todos_item (todoArgs todo)}}

Here the todo is passed as argument to the todoArgs helper, then the output is passed into the Todos_item template.

What is template inclusion?

You “include” a sub-component with the > syntax. By default, the sub-component will gain the data context of the caller, although it’s usually a good idea to be explicit. You can provide a single object which will become the entire data context (as we did with the object returned by the todoArgs helper above), or provide a list of keyword arguments which will be put together into one object, like so:

{{> subComponent arg1="value-of-arg1" arg2=helperThatReturnsValueOfArg2}}

In this case, the subComponent component can expect a data context of the form:

{
  arg1: ...,
  arg2: ...
}

What are attribute helpers?

We saw above that using a helper (or data context lookup) in the form checked={{todo.checked}} will add the checked property to the HTML tag if todo.checked evaluates to true. Also, you can directly include an object in the attribute list of an HTML element to set multiple attributes at once:

<a {{attributes}}>My Link</a>
Template.foo.helpers({
  attributes() {
    return {
      class: 'A class',
      style: {background: 'blue'}
    };
  }
});

Setting tag attributes via helpers (e.g. <div {{attributes}}>) is a neat tool and has some precedence rules that make it more useful. Specifically, when you use it more than once on a given element, the attributes are composed (rather than the second set of attributes simply replacing the first). So you can use one helper to set one set of attributes and a second to set another. For instance:

<template name="myTemplate">
  <div id="my-div" {{classes 'foo' 'bar'}} {{backgroundImageStyle 'my-image.jpg'}}>My div</div>
</template>
Template.myTemplate.helpers({
  classes(names) {
    return {class: names.map(n => `my-template-${n}`)};
  },
  backgroundImageStyle(imageUrl) {
    return {
      style: {
        backgroundImage: `url(${imageUrl})`
      }
    };
  }
});

How can we render raw HTML?

Although by default a mustache tag will escape HTML tags to avoid XSS, you can render raw HTML with the triple-mustache: {{{ }}}.

{{{myHtml}}}
Template.foo.helpers({
  myHtml() {
    return '<h1>This H1 will render</h1>';
  }
});

You should be extremely careful about doing this, and always ensure you aren’t returning user-generated content (or escape it if you do!) from such a helper.

What are block helpers?

A block helper, called with {{# }} is a helper that takes (and may render) a block of HTML. For instance, we saw the {{#each .. in}} helper above which repeats a given block of HTML once per item in a list. You can also use a template as a block helper, rendering its content via the Template.contentBlock and Template.elseBlock. For instance, you could create your own {{#if}} helper with:

<template name="myIf">
  {{#if condition}}
    {{> Template.contentBlock}}
  {{else}}
    {{> Template.elseBlock}}
  {{/if}}
</template>

<template name="caller">
  {{#myIf condition=true}}
    <h1>I'll be rendered!</h1>
  {{else}}
    <h1>I won't be rendered</h1>    
  {{/myIf}}
</template>

How can we use the If / Unless block helper?

The {{#if}} and {{#unless}} helpers are fairly straightforward but invaluable for controlling the control flow of a template. Both operate by evaluating and checking their single argument for truthiness. In JS null, undefined, 0, '', [], and false are considered “falsy”, and all other values are “truthy”.

{{#if something}}
  <p>It's true</p>
{{else}}
  <p>It's false</p>
{{/if}}

How can we use the Each-in block helper?

The {{#each .. in}} helper is a convenient way to step over a list while retaining the outer data context.

{{#each todo in todos}}
  {{#each tag in todo.tags}}
    <!-- in here, both todo and tag are in scope -->
  {{/each}}
{{/each}}

How can we use the Let block helper?

The {{#let}} helper is useful to capture the output of a helper or document subproperty within a template. Think of it just like defining a variable using JavaScript let.

{{#let name=person.bio.firstName color=generateColor}}
  <div>{{name}} gets a {{color}} card!</div>
{{/let}}

Note that name and color (and todo above) are only added to scope in the template; they are not added to the data context. Specifically this means that inside helpers and event handlers, you cannot access them with this.name or this.color. If you need to access them inside a helper, you should pass them in as an argument (like we do with (todoArgs todo) above).

How can we use the Each and With block helpers?

There are also two Spacebars built-in helpers, {{#each}}, and {{#with}}, which we do not recommend using (see use each-in above). These block helpers change the data context within a template, which can be difficult to reason about.

Like {{#each .. in}}, {{#each}} iterates over an array or cursor, changing the data context within its content block to be the item in the current iteration. {{#with}} simply changes the data context inside itself to the provided object. In most cases it’s better to use {{#each .. in}} and {{#let}} instead, just like it’s better to declare a variable than use the JavaScript with keyword.

How strict is Spacebar?

Spacebars has a very strict HTML parser. For instance, you can’t self-close a div (<div/>) in Spacebars, and you need to close some tags that a browser might not require you to (such as a <p> tag). Thankfully, the parser will warn you when it can’t understand your code with an exact line number for the error.

How can we escape curly braces?

To insert literal curly braces: and the like, add a pipe character, |, to the opening braces:

<!-- will render as <h1>All about {{</h1> -->
<h1>All about {{|</h1>

<!-- will render as <h1>All about {{{</h1> -->
<h1>All about {{{|</h1>

What are reusable components?

In UI/UX article we discussed the merits of creating reusable components that interact with their environment in clear and minimal ways.

Although Blaze, which is a simple template-based rendering engine, doesn’t enforce a lot of these principles (unlike other frameworks like React and Angular) you can enjoy most of the same benefits by following some conventions when writing your Blaze components.

A “reusable” component is a component which doesn’t rely on anything from the environment it renders in. It renders purely based on its direct inputs (its template arguments in Blaze, or props in React) and internal state.

In Meteor specifically, this means a component which does not access data from any global sources—Collections, Stores, routers, user data, or similar. For instance, in the Todos example app, the Lists_show template takes in the list it is rendering and the set of todos for that list, and it never looks directly in the Todos or Lists collections.

Reusable components have many advantages:

  1. They are easy to reason about—you don’t need to understand how the data in the global store changes, simply how the arguments to the component change.
  2. They are easy to test—you don’t need to be careful about the environment you render them in, all you need to do is provide the right arguments.
  3. They are easy to add to component style guides—as we’ll see in the section about component style guides, when creating a style guide, a clean environment makes things much easier to work with.
  4. You know exactly what dependencies you need to provide for them to work in different environments.

There’s also an even more restricted type of reusable component, a “pure” component, which does not have any internal state. For instance in the Todos app, the Todos_item template decides what to render solely based on its arguments. Pure components are even easier to reason about and test than reusable ones and so should be preferred wherever possible.

How can we attach functions to a template instance?

If you have common functionality for a template instance that needs to be abstracted or called from multiple event handlers, it’s sensible to attach it as functions directly to the template instance in the onCreated() callback:

mport {
  updateName,
} from '../../api/lists/methods.js';

Template.Lists_show.onCreated(function() {
  this.saveList = () => {
    this.state.set('editing', false);

    updateName.call({
      listId: this.data.list._id,
      newName: this.$('[name=name]').val()
    }, (err) => {
      err && alert(err.error);
    });
  };
});

Then you can call that function from within an event handler:

Template.Lists_show.events({
  'submit .js-edit-form'(event, instance) {
    event.preventDefault();
    instance.saveList();
  }
});

How can we scope DOM lookups to the template instance?

It’s a bad idea to look up things directly in the DOM with jQuery’s global $(). It’s easy to select some element on the page that has nothing to do with the current component. Also, it limits your options on rendering outside of the main document (see testing section below).

Instead, Blaze gives you a way to scope a lookup to within the current template instance. Typically you use this either from a onRendered() callback to setup jQuery plugins (called via Template.instance().$() or this.$()), or from event handlers to call DOM functions directly (called via Template.instance().$() or using the event handler’s second argument like instance.$()). For instance, when the user clicks the add todo button, we want to focus the <input> element:

Template.Lists_show.events({
  'click .js-todo-add'(event, instance) {
    instance.$('.js-todo-new input').focus();
  }
});

Why should we use .js- selectors for event maps?

When you are setting up event maps in your JS files, you need to ‘select’ the element in the template that the event attaches to. Rather than using the same CSS class names that are used to style the elements, it’s better practice to use classnames that are specifically added for those event maps. A reasonable convention is a class starting with js- to indicate it is used by the JavaScript. For instance .js-todo-add above.

How can we pass HTML content as a template argument?

If you need to pass in content to a sub-component (for instance the content of a modal dialog), you can use the custom block helper to provide a block of content. If you need more flexibility, typically just providing the component name as an argument is the way to go. The sub-component can then just render that component with:

{{> Template.dynamic templateName dataContext}}

This is more or less the way that the kadira:blaze-layout package works.

How can we communicate up the component hierarchy?

If you need to communicate up the component hierarchy, it’s best to pass a callback for the sub-component to call. For instance, only one todo item can be in the editing state at a time, so the Lists_show component manages the state of which is edited. When you focus on an item, that item needs to tell the list’s component to make it the “edited” one. To do that, we pass a callback into the Todos_item component, and the child calls it whenever the state needs to be updated in the parent:

{{> Todos_item (todoArgs todo)}}
Template.Lists_show.helpers({
  todoArgs(todo) {
    const instance = Template.instance();
    return {
      todo,
      editing: instance.state.equals('editingTodo', todo._id),
      onEditingChange(editing) {
        instance.state.set('editingTodo', editing ? todo._id : false);
      }
    };
  }
});

Template.Todos_item.events({
  'focus input[type=text]'() {
    this.onEditingChange(true);
  }
});

How can we use onRendered() for 3rd party libraries?

As we mentioned above, the onRendered() callback is typically the right spot to call out to third party libraries that expect a pre-rendered DOM (such as jQuery plugins). The onRendered() callback is triggered once after the component has rendered and attached to the DOM for the first time.

Occasionally, you may need to wait for data to become ready before it’s time to attach the plugin (although typically it’s a better idea to use a sub-component in this use case). To do so, you can setup an autorun in the onRendered() callback. For instance, in the Lists_show_page component, we want to wait until the subscription for the list is ready (i.e. the todos have rendered) before we hide the launch screen:

Template.Lists_show_page.onRendered(function() {
  this.autorun(() => {
    if (this.subscriptionsReady()) {
      // Handle for launch screen defined in app-body.js
      AppLaunchScreen.listRender.release();
    }
  });
});

How can we write smart components with Blaze?

Some of your components will need to access state outside of their data context—for instance, data from the server via subscriptions or the contents of client-side store. As discussed in the data loading and UI articles, you should be careful and considered in how use such smart components. All of the suggestions about reusable components apply to smart components.

What are the two main ways to reuse code in Blaze?

It’s common to want to reuse code between two otherwise unrelated components. There are two main ways to do this in Blaze:

  1. Composition
  2. Libraries

How can we reuse code in Blaze using Composition?

If possible, it’s usually best to try and abstract out the reusable part of the two components that need to share functionality into a new, smaller component. If you follow the patterns for reusable components, it should be simple to reuse this sub-component everywhere you need this functionality.

For instance, suppose you have many places in your application where you need an input to blur itself when you click the “esc” key. If you were building an autocomplete widget that also wanted this functionality, you could compose a blurringInput inside your autocompleteInput:

<template name="autocompleteInput">
  {{> blurringInput name=name value=currentValue onChange=onChange}}
</template>
Template.autocompleteInput.helpers({
  currentValue() {
    // perform complex logic to determine the auto-complete's current text value
  },
  onChange() {
    // This is the `autocompleteInput`'s template instance
    const instance = Template.instance();
    // The second argument to this function is the template instance of the `blurringInput`.
    return (event) => {
      // read the current value out of the input, potentially change the value
    };
  }
});

By making the blurringInput flexible and reusable, we can avoid re-implementing functionality in the autocompleteInput.

How can we reuse code in Blaze using Libraries?

It’s usually best to keep your view layer as thin as possible and contain a component to whatever specific task it specifically needs to do. If there’s heavy lifting involved (such as complicated data loading logic), it often makes sense to abstract it out into a library that simply deals with the logic alone and doesn’t deal with the Blaze system at all.

For example, if a component requires a lot of complicated D3 code for drawing graphs, it’s likely that that code itself could live in a separate module that’s called by the component. That makes it easier to abstract the code later and share it between various components that need to all draw graphs.

What are global helpers?

Another way to share commonly used view code is a global Spacebars helper. You can define these with the Template.registerHelper() function. Typically you register helpers to do simple things (like rendering dates in a given format) which don’t justify a separate sub-component. For instance, you could do:

Template.registerHelper('shortDate', (date) => {
  return moment(date).format("MMM do YY");
});
<template name="myBike">
  <dl>
   <dt>Date registered</dt>
   <dd>{{shortDate bike.registeredAt}}</dd>
 </dl>
</template>

What is this 're-rendering' stuff?

Blaze is intentionally opaque about re-rendering. Tracker and Blaze are designed as “eventual consistency” systems that end up fully reflecting any data change eventually, but may take a few re-runs or re-renders in getting there, depending on how they are used. This can be frustrating if you are trying to carefully control when your component is re-rendered.

The first thing to consider here is if you actually need to care about your component re-rendering. Blaze is optimized so that it typically doesn’t matter if a component is re-rendered even if it strictly shouldn’t. If you make sure that your helpers are cheap to run and consequently rendering is not expensive, then you probably don’t need to worry about this.

The main thing to understand about how Blaze re-renders is that re-rendering happens at the level of helpers and template inclusions. Whenever the data context of a component changes, it necessarily must re-run all helpers and data accessors (as this within the helper is the data context and thus will have changed).

Additionally, a helper will re-run if any reactive data source accessed from within that specific helper changes. You can often work out why a helper has re-run by tracing the source of the reactive invalidation:

Template.myTemplate.helpers({
  helper() {
    // When this helper is scheduled to re-run, the `console.trace` will log a stack trace of where
    // the invalidation has come from (typically a `changed` message from some reactive variable).
    Tracker.onInvalidate(() => console.trace());
  }
});

How can we control re-rendering?

If your helper or sub-component is expensive to run, and often re-runs without any visible effect, you can short circuit unnecessary re-runs by using a more subtle reactive data source. The peerlibrary:computed-field package helps achieve this pattern.

What is this 'lookup order' stuff?

Another complicated topic in Blaze is name lookups. In what order does Blaze look when you write something? It runs in the following order:

  1. Helper defined on the current component
  2. Binding (eg. from #let or #each in) in current scope
  3. Template name
  4. Global helper
  5. Field on the current data context

Why should we use React with Meteor or not?

React uses JSX, with which you write your HTML in JavaScript. While it doesn’t have the logic-view separation most libraries have, it also has the most flexibility. Template functions and event handlers are defined in the same file as the HTML part of the component, which usually makes it easier to understand how they are tied together. https://guide.meteor.com/ui-ux.html

React and Angular enforce a better component structure, which makes developing larger apps easier. (Although you can add component structure to Blaze by following conventions or using the Blaze Components or ViewModel packages.)

Render performance varies a lot depending on the situation. All three libraries are very quick at rendering simple apps, but can take a noticeable amount of time with more complex apps. Angular and React have had more performance optimization work put into them than Blaze and in general will perform better. However, there are some cases when Blaze does better (for instance an #each over a changing cursor).

Why should we use Angular with Meteror or not?

Angular uses HTML with special attribute syntax for logic and events. Template helpers are written in the accompanying JavaScript file along with events, which are called by name from inside HTML attributes. https://guide.meteor.com/ui-ux.html

React and Angular enforce a better component structure, which makes developing larger apps easier. (Although you can add component structure to Blaze by following conventions or using the Blaze Components or ViewModel packages.)

Render performance varies a lot depending on the situation. All three libraries are very quick at rendering simple apps, but can take a noticeable amount of time with more complex apps. Angular and React have had more performance optimization work put into them than Blaze and in general will perform better. However, there are some cases when Blaze does better (for instance an #each over a changing cursor).

What are the global stores that should be avoid when building reusable components?

So which are the global data stores that you should be avoiding in reusable components? There are a few. Meteor is built to optimize speed of development, which means you can access a lot of things globally. Although this is convenient when building “smart” components (see below), you’ll need to avoid these data sources in reusable components:

  1. Your collections, as well as the Meteor.users collection,
  2. Accounts information, like Meteor.user() and Meteor.loggingIn()
  3. Current route information
  4. Any other client-side data stores

What are smart components?

While most of the components in your app should be reusable, they need to get their data passed in from somewhere. This is where “smart” components come in. Such components typically do the following things:

  1. Subscribe to data
  2. Fetch data from those subscriptions
  3. Fetch global client-side state from stores such as the Router, Accounts, and your own stores

Ideally, once a smart component has assembled such a set of data, it passes it off to a reusable component child to render with. Smart components usually don’t render anything apart from one or more reusable children. This makes it easy to separate rendering and data loading in your tests.

A typical use case for a smart component is the “page” component that the router points you to when you access a URL. Such a component typically needs to do the three things above and then can pass the resulting arguments into child components. In the Todos example app, the listShowPage does exactly this, resulting in a template with very simple HTML:

<template name="Lists_show_page">
  {{#each listId in listIdArray}}
    {{> Lists_show (listArgs listId)}}
  {{else}}
    {{> App_notFound}}
  {{/each}}
</template>

The JavaScript of this component is responsible for subscribing and fetching the data that’s used by the Lists_show template itself:

Template.Lists_show_page.onCreated(function() {
  this.getListId = () => FlowRouter.getParam('_id');

  this.autorun(() => {
    this.subscribe('todos.inList', this.getListId());
  });
});

Template.Lists_show_page.helpers({
  // We use #each on an array of one item so that the "list" template is
  // removed and a new copy is added when changing lists, which is
  // important for animation purposes.
  listIdArray() {
    const instance = Template.instance();
    const listId = instance.getListId();
    return Lists.findOne(listId) ? [listId] : [];
  },
  listArgs(listId) {
    const instance = Template.instance();
    return {
      todosReady: instance.subscriptionsReady(),
      // We pass `list` (which contains the full list, with all fields, as a function
      // because we want to control reactivity. When you check a todo item, the
      // `list.incompleteCount` changes. If we didn't do this the entire list would
      // re-render whenever you checked an item. By isolating the reactiviy on the list
      // to the area that cares about it, we stop it from happening.
      list() {
        return Lists.findOne(listId);
      },
      // By finding the list with only the `_id` field set, we don't create a dependency on the
      // `list.incompleteCount`, and avoid re-rendering the todos when it changes
      todos: Lists.findOne(listId, {fields: {_id: true}}).todos()
    };
  }
});

How can we visually test reusable components?

A useful property of reusable components is that you can render them anywhere because they don’t rely on complicated environments. This is very useful when paired with component explorers, debug-only apps that allow you to explore, visualize, and test your UI components. A component explorer does two things:

  1. Indexes your apps components so they are easy to find
  2. Renders components using developer-defined states and stubbed data

See more at https://guide.meteor.com/ui-ux.html#styleguides

How can we throttle method calls on user action?

A large part of your UI involves responding to events initated by the user, and there are some steps that you should take to make sure your application performs well in the face of rapid input. An application lagging in response to user actions is one of the most noticeable performance problems.

It’s typical to make some kind of change to the database when a user takes an action. However it’s important to make sure you don’t do this too rapidly. For instance, if you wish to save the user’s text as they type in a text box, you should take steps to make sure that you don’t send method calls to your server more than every few hundred milliseconds.

To throttle writes, a typical approach is to use underscore’s .throttle() or .debounce() functions. For instance, in the Todos example app, we throttle writes on user input to 300ms:

import {
  updateText,
} from '../../api/todos/methods.js';

Template.Todos_item.events({
  // update the text of the item on keypress but throttle the event to ensure
  // we don't flood the server with updates (handles the event at most once
  // every 300ms)
  'keyup input[type=text]': _.throttle(function(event) {
    updateText.call({
      todoId: this.todo._id,
      newText: event.target.value
    }, (err) => {
      err && alert(err.error);
    });
  }, 300)
});

Typically, you use .throttle() if you are OK with the event happening during the user series of actions (i.e. you don’t mind the multiple, throttled events happening over time, as in this case), whereas you use .debounce() if you want the events to happen whenever (in this example) the user stops typing for 300ms or longer.

How can we limit re-rendering?

Even if you aren’t saving data over the wire to the database on every user input, sometimes you still may wish to update in-memory data stores on every user change. If updating that data store triggers a lot of UI changes, you can see poor performance and missed keystrokes when you update it too often. In such cases you can limit re-rendering by throttling in a similar way how we throttled the method call above. You could also use .debounce() to ensure the changes happen only after the user has stopped typing.

How can we implement per-component loading thing?

Usually it makes for a better UX to show as much of the screen as possible as quickly as possible and to only show loading state for the parts of the screen that are still waiting on data. So a nice pattern to follow is “per-component loading”. We do this in the Todos app when you visit the list page—we instantly render the list metadata, such as its title and privacy settings, and render a loading state for the list of todos while we wait for them to appear.

todos-loading.png

We achieve this by passing the readiness of the todos list down from the smart component which is subscribing (the listShowPage) into the reusable component which renders the data:

{{> Lists_show todosReady=Template.subscriptionsReady list=list}}

And then we use that state to determine what to render in the reusable component (listShow):

{{#if todosReady}}
  {{#with list._id}}
    {{#each todo in (todos this)}}
      {{> Todos_item (todoArgs todo)}}
    {{else}}
      <div class="wrapper-message">
        <div class="title-message">No tasks here</div>
        <div class="subtitle-message">Add new tasks using the field above</div>
      </div>
    {{/each}}
  {{/with}}
{{else}}
    <div class="wrapper-message">
      <div class="title-message">Loading tasks...</div>
    </div>
{{/if}}

What is the placeholder pattern?

You can take the above UI a step further by showing placeholders whilst you wait for the data to load. This is a UX pattern that has been pioneered by Facebook which gives the user a more solid impression of what data is coming down the wire. It also prevents parts of the UI from moving around when data loads, if you can make the placeholder have the same dimensions as the final element.

Is it always a good idea to simply update the contents of a list as quickly as possible?

No. As Dominic points out, it’s not always a good idea to simply update the contents of a list as quickly as possible, as it’s easy to miss changes or get confused about what’s happened.

One solution to this problem is to animate list changes (which we’ll look at in the animation section), but this isn’t always the best approach. For instance, if a user is reading a list of comments, they may not want to see any changes until they are done with the current comment thread.

An option in this case is to call out that there are changes to the data the user is looking at without actually making UI updates. In a system like Meteor which is reactive by default, it isn’t necessarily easy to stop such changes from happening!

However, it is possible to do this thanks to our split between smart and reusable components. The reusable component simply renders what it’s given, so we use our smart component to control that information. We can use a local collection to store the rendered data, and then push data into it when the user requests an update:

Template.Lists_show_page.onCreated(function() {
  // ...

  // The visible todos are the todos that the user can
  // actually see on the screen (whereas Todos are the
  // todos that actually exist)
  this.visibleTodos = new Mongo.Collection(null);

  this.getTodos = () => {
    const list = Lists.findOne(this.getListId());
    return list.todos({}, {limit: instance.state.get('requested')});
  };
  // When the user requests it, we should sync the visible todos to
  // reflect the true state of the world
  this.syncTodos = (todos) => {
    todos.forEach(todo => this.visibleTodos.insert(todo));
    this.state.set('hasChanges', false);
  };
  this.onShowChanges = () => {
    this.syncTodos(this.getTodos());
  };

  this.autorun((computation) => {
    const todos = this.getTodos();

    // If this autorun re-runs, the list id or set of todos must have 
    // changed, so we should flag it to the user so they know there
    // are changes to be seen.
    if (!computation.firstRun) {
      this.state.set('hasChanges', true);
    } else {
      this.syncTodos(todos);
    }
  });
});

Template.Lists_show_page.helpers({
  listArgs(listId) {
    const instance = Template.instance();
    const list = Lists.findOne(listId);
    const requested = instance.state.get('requested');
    return {
      list,
      // we pass the *visible* todos through here
      todos: instance.visibleTodos.find({}, {limit: requested}),
      requested,
      countReady: instance.countSub.ready(),
      count: Counts.get(`list/todoCount${listId}`),
      onNextPage: instance.onNextPage,
      // These two properties allow the user to know that there
      // are changes to be viewed and allow them to view them
      hasChanges: instance.state.get('hasChanges'),
      onShowChanges:instance.onShowChanges
    };
  }
});

The reusable sub-component can then use the hasChanges argument to determine if it should show some kind of callout to the user to indicate changes are available, and then use the onShowChanges callback to trigger them to be shown.

When should we implement Optimistic UI or not?

One nice UX pattern which Meteor makes much easier than other frameworks is Optimistic UI. Optimistic UI is the process of showing user-generated changes in the UI without waiting for the server to acknowledge that the change has succeeded, resulting in a user experience that seems faster than is physically possible, since you don’t need to wait for any server roundtrips. Since most user actions in a well-designed app will be successful, it makes sense for almost all parts of an app to be optimistic in this way.

However, it’s not always necessarily a good idea to be optimistic. Sometimes we may actually want to wait for the server’s response. For instance, when a user is logging in, you have to wait for the server to check the password is correct before you can start allowing them into the site.

So when should you wait for the server and when not? It basically comes down to how optimistic you are; how likely it is that something will go wrong. In the case of a password, you really can’t tell on the client, so you need to be conservative. In other cases, you can be pretty confident that the Method call will succeed, and so you can move on.

For instance, in the Todos example app, when creating a new list, the list creation will basically always succeed, so we write:

import { insert } from '../../api/lists/methods.js';

Template.App_body.events({
  'click .js-new-list'() {
    const listId = insert.call((err) => {
      if (err) {
        // At this point, we have already redirected to the new list page, but
        // for some reason the list didn't get created. This should almost never
        // happen, but it's good to handle it anyway.
        FlowRouter.go('App.home');
        alert('Could not create list.');
      }
    });

    FlowRouter.go('Lists.show', { _id: listId });
  }
});

We place the FlowRouter.go('Lists.show') outside of the callback of the Method call, so that it runs right away. First we simulate the method (which creates a list locally in Minimongo), then route to it. Eventually the server returns, usually creating the exact same list (which the user will not even notice). In the unlikely event that the server call fails, we show an error and redirect back to the homepage.

Note that the listId returned by the list method (which is the one generated by the client stub) is guaranteed to be the same as the one generated on the server, due to the way that Meteor generates IDs and ensures they are the same between client and server.

How can we indicate that a write is in progress?

Sometimes the user may be interested in knowing when the update has hit the server. For instance, in a chat application, it’s a typical pattern to optimistically display the message in the chat log, but indicate that it is “pending” until the server has acknowledged the write. We can do this easily in Meteor by simply modifying the Method to act differently on the client:

Messages.methods.insert = new ValidatedMethod({
  name: 'Messages.methods.insert',
  validate: new SimpleSchema({
    text: {type: String}
  }).validator(),
  run(message) {
    // In the simulation (on the client), we add an extra pending field.
    // It will be removed when the server comes back with the "true" data.
    if (this.isSimulation) {
      message.pending = true;
    }

    Messages.insert(message);
  }
})

Of course in this scenario, you also need to be prepared for the server to fail, and again, indicate it to the user somehow.

How can we deal with unexpected failure?

We’ve seen examples above of failures which you don’t really anticipate will happen. It’s difficult and inefficient to defend against every possible error, however unlikely. However, there are some catch-all patterns that you can use for unexpected failures.

Thanks to Meteor’s automatic handling of optimistic UI, if a method unexpectedly fails the optimistic changes will roll back and the Minimongo database will end up in a consistent state. If you are rendering directly from Minimongo, the user will see something that is consistent, even if it’s not what they anticipated of course. In some cases when you have state you are keeping outside of Minimongo, you may need to make changes to it manually to reflect this. You can see this in the example above where we had to update the router manually after an operation failed.

However, it’s terrible UX to simply jump the user to an unexpected state without explaining what’s happened. We used a alert() above, which is a pretty poor option, but gets the job done. One better approach is to indicate changes via a “flash notification”, which is a UI element that’s displayed “out-of-band”, typically in the top right of the screen, given the user some indication of what’s happened. Here’s an example of a flash notification in Galaxy, at the top right of the page:

galaxy-flash-notification.png

How can we animate change in visibility?

Probably the most fundamental type of UI change that requires animation is when items appear or disappear. In Blaze, we can use the percolate:momentum package to plug a standard set of animations from the velocity animation library into such state changes. A good example of this is the editing state of the list from the Todos example app:

{{#momentum plugin="fade"}}
  {{#if instance.state.get 'editing'}}
    <form class="js-edit-form list-edit-form">...</form>
  {{else}}
    <div class="nav-group">...</div>
  {{/if}}
{{/momentum}}

Momentum works by overriding the way that child HTML elements appear and disappear. In this case, when the list component goes into the editing state, the .nav-group disappears, and the form appears. Momentum takes care of the job of making sure that both items fade, making the change a lot clearer.

How can we animate changes to attributes?

Another common type of animation is when an attribute of an element changes. For instance, a button may change color when you click on it. These type of animations are most easily achieved with CSS transitions. For example, we use a CSS transition for the hover state of links in the Todos example app:

a {
  transition: all 200ms ease-in;
  color: @color-secondary;
  cursor: pointer;
  text-decoration: none;

  &:hover { color: darken(@color-primary, 10%); }
  &:active { color: @color-well; }
  &:focus { outline:none; } //removes FF dotted outline
}

How can we animate page changes?

Finally, it’s common to animate when the user switches between routes of the application. Especially on mobile, this adds a sense of navigation to the app via positioning pages relative to each other. This can be done in a similar way to animating things appearing and disappearing (after all one page is appearing and other is disappearing), but there are some tricks that are worth being aware of.

Let’s consider the case of the Todos example app. Here we do a similar thing to achieve animation between pages, by using Momentum in the main layout template:

{{#momentum plugin="fade"}}
  {{#if Template.subscriptionsReady}}
    {{> Template.dynamic template=main}}
  {{else}}
    {{> App_loading}}
  {{/if}}
{{/momentum}}

This looks like it should just work, but there’s one problem: Sometimes the rendering system will prefer to simply change an existing component rather than switching it out and triggering the animation system. For example in the Todos example app, when you navigate between lists, by default Blaze will try to simply re-render the Lists_show component with a new listId (a changed argument) rather than pull the old list out and put in a new one. This is an optimization that is nice in principle, but that we want to avoid here for animation purposes. More specifically, we want to make sure the animation only happens when the listId changes and not on other reactive changes.

To do so in this case, we can use a little trick (that is specific to Blaze, although similar techniques apply to other view layers) of using the fact that the #each helper diffs arrays of strings, and completely re-renders elements when they change.

<template name="Lists_show_page">
  {{#each listId in listIdArray}}
    {{> Lists_show (listArgs listId)}}
  {{else}}
    {{> App_notFound}}
  {{/each}}
</template>
Template.Lists_show_page.helpers({
  // We use #each on an array of one item so that the "list" template is
  // removed and a new copy is added when changing lists, which is
  // important for animation purposes.
  listIdArray() {
    const instance = Template.instance();
    const listId = instance.getListId();
    return Lists.findOne(listId) ? [listId] : [];
  }
});

How can we display a template?

{{> templateName}}

How can we limit the scope of the DOM query to this template instance?

Use the $ method of the templateInstance:

templateInstance.$('selector').droppable({
  drop: function(evt, ui) {
    // do something
  });
});

What is a template instance?

Let says that we have a template name A, and it got rendered twice on the page, we have two instances of this template.

What is the purpose of Template.instance()?

When called inside a helper, Template.instance() returns current template instance.

How can we dynamically include or display different templates reactively?

In addition to using static text to include subtemplates, we can dynamically include a template based on the return value from a helper. That way we can reactively switch template without having to maintain complex if/else structures inside templates. This can be powerful in combination with reactive data sources. See page 59 of the "Meteor In Action" book.

<template name="someName">
  <div class="left">
    {{> Template.dynamic template=templateNameLeft }}
  </div>
  <div class="right">
    {{> Template.dynamic template=templateNameRight }}
  </div>
</template>

Template.someName.helpers({
  templateNameLeft: function() {
    return "partialsUserProfile";
  },
  templateNameRight: function() {
    return "partialNewsStream";
  }
});

How can we use the if/else block tag?

{{#if image}}
  <img src="{{image}}"/>
{{else}}
  <p>Sorry, no image available.</p>
{{/if}}

There is no {{elseif}} tag. To deal with more case than true, and false, you'll need to use nested if-else structure inside your template or adjust your JavaScript code so that it do the processing instead of the template.

Can the each block accept an array?

Yes.

Can the each block accept a helper function?

Yes.

How can we set the data context for a block or sub-template?

{{#with profile}}
  <p>{{name}}</p>
  <ul>
  {{#each skills}}
    <li>{{this}}</li>
  {{/each}}
  </ul>
{{/with}}

In the above code, the #with block helper takes an object 'profile' as argument and set it as the data context for its block. Then the #each block helper looks at the skills array or help, and set each element as the data context for its block.

How can we access elements of an array?

{{skills.[0]}}

Notice the dot between skills and the square bracket.

How can we pass parameters to helpers?

To pass parameters to a helper functions, simply write the parameter you wan to pass after the helper function, separated by a white space. The order in which you pass the parameters will be the same as defined in the function itself:

{{#if hasMoreSkills skills}}
  ...
{{/if}}

Block tags are technically helpers, and they are functions. In the above code, the '#if' is a function that that one or two parameters. Now, the question is what does this 'if' function do with the supplied parameters. If 'hasMoreSkills' is a function, will the 'if' function pass 'skills' as parameter to the 'hasMoreSkills' helper?. This depends on how the built-in 'if' function is defined.

How can we define our own custom block helpers?

Also globally available and very useful are custom block helpers. They allow you to build reusable UI components or widgets. Note that helpers can be defined / used even without any JavaScript. Supposed you defined a new block helper named #sidebarWidget; you also need to define a template of the same name. The template will be injected where the block helper is called. Inside the template you use the partials syntax to include the output of Template.contentBlock. You can also access any other elements from the data context that may be passed to the block helper.

When #sidebarWidget is called from within a template, it places its own contents between the {{#sidebarWidget}} and {{/sidebarWidget}} tags by including Template.contentBlock.

// Defining the sidebarWidget custom block helper by defining a template with the same name:
<template name="sidebarWidget">
  <div class="sidebar-widget-box">
    <div class="title">{{this.title}}</div>
    <div class="content">
       {{> Template.contentBlock}}
    </div>
  </div>
</template>

// Using the sidebarWidget custom block helper
<template name="coderOfTheMonth">
  {{#sidebarWidget title="Coder of the month"}}
    Manuel
  {{/sidebarWidget}}
</template>

As you can see, defining the #sidebarWidget custom block helper does not involve JavaScript.

What is a partial?

It is a sub-template.

What is the purpose of Template.contentBlock?

It is used to make custom block helpers

What is the purpose of Template.elseBlock?

Beside Template.contentBlock, there's also a Template.elseBlock that relates to the content block after an {{else}} template tag, so that you can enhance your custom block helpers with simple control structure:

// Define a custom block helper named isFemale, that has a helper named 'eq':
<template name="isFemale">
  {{#if eq this 'w'}}
    {{> Template.contentBlock}}
  {{else}}
    {{> Template.elseBlock}}
  {{/if}}
</template>
Template.isFemale.helpers({
  eq: function (a,b) {
    return a == b;
  }
});

// Using the 'isFemale' custom block helper:
<template name="someTemplateName">
  {{#isFemale gender}}
    Mrs.
  {{else}}
    Mr.
  {{/if}}
</template>

How can we comment out a block inside a template?

{{!-- your comments --}}

{{!--
--}}

How can we access the data context of a template instance?

Inclusion tags ({{> foo}}) and block tags ({{#foo}}) take a single data argument, or no argument. Any other form of arguments will be interpreted as an object specification or a nested helper:

  1. Object specification: If there are only keyword arguments, as in {{#with x=1 y=2}} or {{> prettyBox color=red}}, the keyword arguments will be assembled into a data object with properties named after the keywords.
  2. Nested Helper: If there is a positional argument followed by other (positional or keyword arguments), the first argument is called on the others using the normal helper argument calling convention.

Then you retrieve the data context through the templateInstance.data property:

  1. In an onCreated, onRendered or onDestroyed callback, the template instance is directly available in this.
  2. In a helper or in the HTML part of the template, the data context is directly available in this (no need to look for its data child property). In a helper, you can also access the template through Template.instance().
  3. In an event handler, the template instance is passed as the 2nd argument of the listener.

How can we access nested data?

Use the dot notation:

{{house.name}}

How can we access the parent's data context?

The #with and #each block helper change the data context. Using subtemplates give you greater flexibility and manageability. When you include a template, it inherits the parent's data context. To access parent's attributes, use the ../ notation:

{{../_id}}

How can we determine the index of the current element in an array?

If the {{@index}} helper is available for your version of Meteor, you can use it:

{{#each plant in plants}}
  Index: {{@index}}
{{/each}}

If the {{@index}} helper is not available for your version of Meteor, you can create a global helper name 'withIndex':

Template.registerHelper('withIndex', function(list) {
  var withIndex = _.map(list, function(v,i) {
    if (v === null) return;
    v.index = i;
    return v;
  });
  return withIndex;
});

The above code use the _.map function which is provided by the Underscore library. Underscore is shipped with Meteor, and you do not have to add it to your project. First, it check to see if v is null. If not, it add a new property to the object named 'index' with the value of the current array position (i). The new helper 'withIndex' takes a list and gives you a new list with exactly the same elements in the same order, with an additional index property attached to each object. Inside your template, you can use {{index}} to access the index of the current element because 'index' is now a property of the object just like any other property.

Inside our template, adjust the #each block tag to pass plants to the withIndex function:

{{#each withIndex plants}}
  ...
{{/each}}

What is the purpose of Template.parentData()?

You can access the parent's data context using the global Template object:

Template.parentData(1).plants

If you do not put an argument inside the paranthesis, it default to 1, which means the data context one level up is referenced. Inside the template, we can use {{../plants}}

How can we remove an element from an array?

var index = evt.target.getAttribute('data-index');
var plants = Template.parentData(1).plants;
plants.splice(index,1);
var modifier = {$set: {'plants': plants}};
CollectionName.update(id, modifier);

What is the advantage of using autorun inside the onCreated callback of a template?

The advantage of using autorun inside a template context is that once the template is destroyed, the autorun function is destroyed as well:

Template.houseForm.onCreated(function() {
  this.autorun(function() {
    ...
  });
});

How can we cause a template to be re-evaluated when a variable is changed?

Template.templateName.onCreated(function() {
  this.variableName = new ReactiveVar(false);
});

Template.templateName.helpers({
  'getValue': function() {
    // Note that 'this' inside a template helper may not refer to the template instance
    return Template.instance().variableName.get();
  }
});

<template name="...">
  {{#if getValue}}
    ...
  {{else}}
    ...
  {{/if}}
</template>
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License