Meteor: Using while loop in Template - javascript

How would I use a while loop in meteor blaze?
I tried using {{unless}} but that did not work. This is what I tried:
<template name="homePage">
<h2>Welcome to home page! </h2>
{{#unless numberOfDays 0}}
<span>hi</span>
{{numberOfDays--}}
{{/#unless}}
</template>
It did not work at all.

There is no #while in spacebars, the templating engine that is default in meteor-blaze.
The #unless keyword is a negated #if, a conditional on something not being truthy. The unless block is not a loop, it can only run once. Like if, the block will either run or not run. The #unless runs if the condition is not truthy.
The only loop construct is #each. You could emulate the behavior of a for or while loop by calculating the results outside the template and placing them in an array variable. In the template, call #each on the array variable.
Although writing a customized handlebars block helper can be used to make custom iteration such as a while loop, Meteor's spacebars is a fork of the handlebars code, and may require a slightly different syntax.
For most simple uses, #each is enough . Reformatting data will often allow #each to be used in a natural way.
From the Spacebar docs
#Each
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 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.

Related

Looping through two arrays simultaneously and printing in Handlebars Ember

I have two arrays NOVNoticeTypeName and NOVNumber, they both have the same number of elements, now I want to loop through one of them and print the values side by side as below:
{{#each v.NOVNoticeTypeName as |nntn index|}}
{({{v.NOVNoticeTypeName.[index]}} {{v.NOVNumber.[index]}})
{{/each}}
I understand looping is a mess in the Ember handlebars.
How can I achieve this?
First of all I don't share your opinion that looping is a mess in Ember templates. Would be great if you don't put such opinions as a facts. Especially if it comes without any argument.
What you want to achieve could be done with a combination of an {{each}} loop and a template helper. As your example already shows {{each}} loop yields the current value and index. You can't access an array element directly using the index as in JavaScript array[index] in an Ember template but you could achieve the same using a template helper. A template helper, lets call it {{object-at}} that gets an index as first and an array as second argument and returns array[index].
Lets see an example how that would work:
{{#let (array 'a' 'b' 'c') as |letters|}}
{{#let (array '1' '2' '3') as |numbers|}}
<ul>
{{#each letters as |letter index|}}
{{letter}} {{object-at index numbers}}
{{/each}}
</ul>
{{/let}}
{{/let}}
Such a template helper wouldn't be to complex. But you don't have to worry at all, cause it's already available as part of ember-composable-helpers.

Using result of one helper function in another helper function within Handlebars

I am checking if there is anyway that I can use the result of one helper function in another helper function and how can I use it, for example, I am looping through as below
{{#each v.NOVNumber as |vv iindex|}}
And then if I am getting another element as below, using the same index:
{{get v.NOVNoticeTypeName iindex}}
Can I use this element that we have got in a statement like below, to check if that is first or last element etc?
{{#if (isFirst v.NOVNumber vv)}}
You you can use helpers together to create more powerful functions. Ember Composable Helpers provides both a good pattern for using helpers together as well as the specific has-next and has-previous helpers that you need to know if an element is first of last.
An example using has-next
{{#if (has-next page pages)}}
<button>Next</button>
{{/if}}

Node.js Handlebars {{object}} does not render inside {{each}} loop, but renders outside of loop (and other {{object_names}} render within the loop)

I am using Express, Node, & Handlebars and I can't figure out why my {{object_one}} won't render within an {{each}} loop, but it renders {{object_two}} from within and {{object_one}} outside.
Here is example since I'm not sure I'm describing this well:
{{#each inline_upsell_amounts}}
<div class="col-4">$ {{this}}</div>
{{/each}}
<p>This shows the 'base_url' value: {{base_url}}</p>
So inside the loop base_url renders as empty or ''. the value of base_url is a string (url 'http://something.com' ).
It renders correct outside of the each loop, and {{inline_ab_refcode}} also a string renders fine within the loop.
I've tried different names, different values, making a helper, wrapping with IF. I can't figure out this odd bug I have.
Hopefully it's something silly that you can see?!
You miss something : in the loop {{base_url}} is not the same as outside the loop :
In the loop {{base_url}} is actually {{inline_upsell_amounts.0.base_url}} or {{inline_upsell_amounts.1.base_url}} and so on ... outside of it it is {{base_url}}. Because the argument of the loop becomes the new reference.
What you can do is refer to the parent item and use {{../base_url}} inside the loop and {{base_url}} outside. If you need a reference that is always the same you can also use {{#root/base_url}} that will always be the base_url of the root element.
So your code will look like that :
{{#each inline_upsell_amounts}}
<div class="col-4">$ {{this}}</div>
{{/each}}
<p>This shows the 'base_url' value: {{base_url}}</p>
I hope I've been clear enough.

Is there a way to pass a Handlebars partial (with variables) into another helper?

So there is a template file that is generating a few different layouts for a component in my webpage with different variables dictating sizes and whatnot. So in order to reduce the number of files in the project, I'm trying to reuse the template files for code snippets instead of having dedicated files for them. Through sub expressions, I've had the idea of doing something like this:
{{ escape (template var1=var1 var2=var2 var3=var3) }}
where escape is a helper that takes a string and escapes it (funnily enough), and:
(template var1=var1 var2=var2 var3=var3)
is supposed to have the same effect as {{> template var1=var1 var2=var2 var3=var3 }}, returning complete markup presumably as a string.
The helper doesn't seem to be receiving any string since running typeof on the parameter is returning undefined. I had assumed since {{> template var1=var1 var2=var2 var3=var3 }} is being used higher up in the file, that was registering it for use within the rest of the file, but now I'm thinking that's not how Handlebars does its thing.
Is it possible to retrieve the partial like this or does it need to use the {{> syntax (which doesn't work)?
At the time I asked this question, I was a bit confused with how a context was applied to a partial programmatically. Now that I've done a bit more research (I did try before asking but got nowhere), I now know that Handlebars.compile(partial) will return an object for the given partial and allow a context to be given through partial(context) which should be returned.
Sample Code
function escape(partial) {
let compiledPartial = Handlebars.compile(partial);
let context = { greeting: "Hello World!" };
return compiledPartial(context);
}

Check for duplicates in each loop in Ember.js

I have a very simple template loop:
{{#each}}
{{title}}
{{/each}}
Fact is, my title can appear in my data multiple times (of course other parts of the record change) but I want to make sure that there are no duplicates for a given property (in this case title). Is there any way to put some logic inside the template to make sure to exclude duplicates?
I tried using an Handlebar Helper, but I really didn't make much progress with that.
You should put a computed property on the controller that's backing the template. Ember has a method uniq that will return the unique items in the array.
uniqueItems: function(){
return this.get('model').getEach('title').uniq();
}.property('model.#each.title')
http://emberjs.jsbin.com/IMOMoliB/5/edit

Categories