{{#each array}}
{{#if conditoin}}
...
{{else}}
{{#if condition}}
....
{{/if}}
...
{{#if condition}}
...
{{/if}}
{{/if}}
{{/each}}
so this is my nested condition but in the first closing if under else an error is thrown:
Unexpected closing template tag {{/if}}
This looks correct to me, but it could be that you simply don't have balanced tags (e.g., div) inside your conditional blocks. Keep in mind that Meteor uses strict xhtml parsing. So things that are OK to a browser, such as
<ul>
<li>one
<li>two
</ul>
are not OK to Meteor (missing </li> tags).
I simply created a meteor project and copy/paste from the example 'basic' files (found at https://github.com/EventedMind/iron-router/tree/devel/examples/basic) replacing Meteor project .html and .js files.
On the HTML, the example failed to include any template inclusion so I added {{> Home}} and run Meteor between the 'body' block.
<body>
{{> Home}}
</body>
The complete HTML code is:
basic
<body>
{{> Home}}
</body>
<template name="Home">
<h1>Home</h1>
{{> Nav}}
<p>
Data Title: {{title}}
</p>
</template>
<template name="One">
<h1>Page One</h1>
{{> Nav}}
</template>
<template name="Two">
{{> Nav}}
<h1>Page Two</h1>
</template>
<template name="Nav">
<ul>
<li>
Home
</li>
<li>
Page One
</li>
<li>
Page Two
</li>
</ul>
</template>
The .js code is exactly as in the example.
When run, however, it failed to change or route to pages One and Two. It simply stays on Home.
I am learning to work with it but I don't seem to get it right even on the simplest of examples. What I am doing wrong?
Router.map is now deprecated and replaced by Router.route, however, there seem to be a few bugs they're still ironing out. First of all, I've found that their basic routing function rarely works at the moment, so don't use it for now, i.e.:
Router.route('/path', function() {
this.render('pathName');
});
Whether this is due to compatibility issues or something else, I have no idea. I have found a very standard formula that seems to work quite nicely however, and that is to replace the function with the built in "Route Specific Options", and specify exactly what you want, like so using basic JSON:
Router.route('/path', {
name: 'pathName',
path: '/path',
template: 'templateName',
data: function () {
title: 'My Title'
}
});
Notice the path: option. This should not be necessary, as the path is defined as the first parameter of your Router function, but they specifically state in the documentation that you may need to include a path: in your routes for backwards compatibility. I'm sure once they get everything operating smoothly you'll be able to delete this entirely.
Also, the template: option should not be necessary if the templateName is the same as your /path (and for that matter, the pathName: option should not be necessary if it is also the same as your /path), but I've found including them just makes life easier as sometimes they will not function properly otherwise.
In short, when the bugs are gone, simple templates like yours will be called with one line:
Router.route('/one');
The end result is that they have simplified how routes are called and defined, but unfortunately, it just doesn't seem to working as planned at the moment. I hope this helps you with understanding the difference between Router.map and Router.route now.
Plus, the main problem with your code before was that you inserted the partial {{> Home}} between your body tag, which isn't necessary and messes things up, as that partial will always remain even as meteor attempts to route between and load other templates. In essence, when Meteor went to load template "One" it had to do so on top of template "Home", meaning you had, among other things, two {{> Nav}} partials loading at once.
When using iron router package you must leave body tag as it is or don't include it at all, i'm using a layout template but its not necessary:
basic.html:
<head>
<title>basic</title>
</head>
<body>
</body>
<template name="layout">
{{> yield}}
</template>
<template name="Home">
{{> Nav}}
<h1>Home</h1>
<p>
Data Title: {{title}}
</p>
</template>
<template name="One">
{{> Nav}}
<h1>Page One</h1>
</template>
<template name="Two">
{{> Nav}}
<h1>Page Two</h1>
</template>
<template name="Nav">
<ul>
<li>
Home
</li>
<li>
Page One
</li>
<li>
Page Two
</li>
</ul>
</template>
basic.js:
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function(){
this.route('Home', {path: '/', data: {title: 'My title'}});
this.route('One');
this.route('Two');
});
and now works properly.
What is the least code / very simple way to dynamically show a html element "the meteor way"? Jquery.show() is very simple but doesn't work and it seems odd that Meteor way requires lines and lines of code? Any suggestions welcome!
Use UI.dynamic. There's a really good example of how to do it in this post on creating a simple modal. Here are the relevant snippets:
<template name="modal">
{{#if activeModal}}
<div class="modal">
{{> UI.dynamic template=activeModal}}
</div>
{{/if}}
</template>
Template.modal.helpers({
activeModal: function() {
return Session.get('activeModal');
}
});
How do I access template variables within an {{each}} in Meteor?
For example,
<template name="test">
{{#if someValue}}It works!{{/if}}<br>
{{#each thing}}
{{#if someValue}}It works in Each!{{/if}}<br>
{{/each}}
</template>
Expected behavior is to see "It works!" and "It works in Each!". someValue is not a property of any of the objects in the thing array.
My question is how to access the template scope from within the {{each}}?
You can use .., for example:
{{#each thing}}
{{../this}}
{{../fooField}}
{{/each}}
You can also use any of those as an argument to a helper.
I'm making a movie search based on data I'm getting from rotten tomatoes api. I'm using handlebars.js. So far I've got this template and it works just fine.
<div class="info">
<h3>{{title}}</h3>
<span> Year: {{year}} </span>
<span> Studio:{{studio}} </span>
<span> Synopsis:{{synopsis}} <span>
</div>
However, some of of movies don't have a studio provided so I'd like to make that in this case no "Studio:" would be printed. This is my code to do so:
{{#if studio}}
<span> Studio:{{studio}} </span>
{{/if}}
I've copied it from example provided on handebars.js page. Still it doesn't work. Could anyone explain me what I'm missing? I suppose there is no need to use Handlebars.registerHelper since I'm using this simple if statement. Or is it?
see this jsFiddle. You should not have any issue with that.
From documentation.
You can use the if helper to conditionally render a block. If its
argument returns false, undefined, null, "" or [] (a "falsy" value),
Handlebars will not render the block.
So check your 'studio' value.
Code that i have fiddled.
HTML:
<p>{{name1}}</p>
{{#if name2}}
<p>{{name2}}</p>
{{/if}}
<p>End</p>
js:
this.$el.html(temp({name1: 'stack'}));