Handlebars: Using #key in dot notation - handlebars.js

This should be a simple thing to do in Handlebars, but I can't seem to do it.
I have two objects:
a: {
key1: "w",
key2: "x"
}
b: {
key1: "y",
key2: "z"
}
I'm trying something like this:
{{#each a}}
{{b.#key}}
{{/each}}
<!-- Should output "y z" but it doesn't! -->
What am I doing wrong here?

I am not really sure if you can use "#key" in the dot notation, because every-time you try doing the same, Handlebars compilation fails.
Moreover, b is not an object present in a. So, if you're iterating over a, you can never get keys of b.
{{#each b}}
{{#key}}
{{/each}}
This is the block of code that would iterate over "b" object, and would print all the keys present in b, meaning "y" and "z".
However, if you change your JSON to,
a: {
'kx':'x',
'ky':'y',
b:{
'by':'y',
'bz':'z'
}
}
then, you may get the keys of b, by saying,
{{#each a.b}}
{{#key}}
{{/each}}
Which would again, give you the desired result, i.e. by and bz.

Related

Remove white space between words in a handlebar expression

I’ve a handlebar expression which is giving me a dynamic string. I want to remove the white space between letters and use it as a div id. I know I can do this using JS. But is there a way to do this within handlebar template?
{{name}} is giving me “abc xyz” and I want “abcxyz” string.
What you can do is register a helper yourself and use it in your template to replace the white-space in the string with nothing.
Handlebars.js has a function registerHelper(String, Function) which (as you see) takes a string (the name of your helper) and a function that will return the result of your helper.
For example, if we want a helper function that replaces "Facebook" with "Google" in a given string you could do something like this.
Handlebars.registerHelper('replace', function(string) {
return string.replace('Facebook', 'Google');
});
In the template we would invoke it like {{replace "Hello, Facebook!"}} and it would return Hello, Google!.
In case of a multipurpose function (what it obviously should be in this case instead of the example I gave) you would pass the string to invoke the replacement on, the string to replace and what it should be replaced with.
Handlebars.registerHelper('replace', function(string, search, replace) {
return string.replace(search, replace);
});
In the same way as we did before we would invoke it in the template using {{replace "Hello, Facebook!" "Facebook" "Google"}}.
If you want to avoid writing your own helpers. You can use the following module : https://github.com/helpers/handlebars-helpers
simply install it
npm install --save handlebars-helpers
And you're good to go, you can use the following helper for your issue :
{{replace name " " ""}}
Here's another usage example :
{{replace "a b a b a b" "a" "z"}}
<!-- results in: 'z b z b z b' -->

return multiple different values from single helper function?

I have a helper compare that returns a css class that simply highlights the text. "better" makes it green, "worse" colors it red. Basically the function compares 2 numbers (the compare function thats commented out does the same as the ternary below it). How can i compare multiple values in the same helper function? I know i could just create a bunch more helper functions and compare all the data 1 by 1, but im sure theres a better way. Heres what the template looks like :
Return the multiple values as an object from your helper then refer to the keys in your template.
js:
Template.myTemplate.helpers({
compare(){
return { key1: value1, key2: value2, ... keyN: valueN};
}
});
html:
{{compare.key1}} etc...
You'd have to pass them as arguments within the function definition itself, something like this should do the trick:
compare: function( number1, number2 ) {
return number1 > number 2 ? "better" : "worse";
}

"Failed to compute" error because of unexpected operation inside #if

Here is the problem (Ractive.js v0.7.3): http://jsfiddle.net/Inversion/hLym2xcy/
r = new Ractive
el: 'cont'
template: '''
{{#task.options}}
{{#if pros}}
inside if
{{#each filter(.pros)}}<li class='{{set_class(.)}}'>+{{.v}}</li>{{/each}}
{{/if}}
{{/task.options}}
'''
data:
task:
options: [{pros:[{v:1}]}]
set_class: (o)-> o.v
filter: (arr)-> console.log(arr);arr || []
setTimeout(
-> r.set('task.options.0.pros', undefined)
2000
)
On r.set operation "inside if" is not printed out as expected, but #each tries to work with an undefined array which is not expected.
I cannot guarantee presence of an pros array and that's why I used {{#if pros}} to do not use it, but seems like it doesn't work.
console.log(arr) is added to see if filter is actually called, and it is.
Also when I try to return [] from the filter it still calls set_class which is unexpected because there is nothing to iterate.
Is there a way to overcome these unexpected problems?
Thanks!
Seems like it is a known problem and will be fixed in v0.8

Meteor - What is Spacebars.kw {hash: Object}

I'm attempting to write a Meteor package which can be placed inside templates. So I first attempted to register a helper.
Template.registerHelper('testHelper', function(a, b) {
console.log(a);
console.log(b);
})
I've added the package inside /packages, and in my client template, when I added {{testHelper "hello" "meow"}}, the console logged hello and meow, which is what I expected.
When I added {{testHelper "hello"}}, I expected the console to log hello and null, since nothing was passed as the second parameter. But instead it returned hello and an object - Spacebars.kw {hash: Object}
What is this Spacebars.kw {hash: Object}? What can I do if I want it to return null instead?
Spacebars.kw contains a hash object that has a hash of input parameters.
Meteor has two methods to match up methods, one is direct matching which is where the parameters are directly input, e.g {{testHelper "variable1" "variable2" "variable3"}}, would match up as function(a,b,c) as variables 1-3 matching up to a,b and c respectively.
The second method of input is using a hash:
{{testHelper a="variable1" b="variable2" c="variable3"}}
This would give a single parameter to function(a) where a is a Spacebars.kw object.
The Spacebars.kw object would have a subobject called hash with a structure that matches:
{ "a" : "variable1",
"b" : "variable2",
"c" : "variable3" }
Meteor will attempt to match up the first param directly, but the subsequent parameters will be matched up as hashes incase the second input is empty such as in the case where you use {{testHelper 'hello'}} where b would be null, so it's given as the hash instead.
Its generically given as this, so if you get b as a Spacebars.kw object, you can assume there was no second input. The alternative is you could use the hash style declarations and then directly check if the hash value is null:
{{testHelper text="Hello"}}
{{testHelper text="Hello" othertext="Hellooo"}}
and the helper:
Template.registerHelper('testHelper', function(kw) {
console.log(kw.hash.text);
console.log(kw.hash.othertext);
});

How to represent Array of integers in handlebar.js

I have a json object "FoundAt" : [1, 3]
How do I represent the values in the array using handlebar.js?
If you are referring to iterating the array you can do so using {{each}} block, with reference to the above defined array use the following:
{{#each jsonObjectName.FoundAt}}
{{this}}
{{/each}}
OR
{{#each number in jsonObjectName.FoundAt}}
{{number}}
{{/each}}
Look for Simple Iterators in the official documentation

Resources