How to evaluate expression in handlebars - handlebars.js

I need to evaluate an expression which I am supposed to append.
eAddressType can be M, E, PH or FX
What will be the best way to evaluate the expression initData.alternateContactLabelM using a combination of (alternateContactLabel + eAddressType)?
<ux-list-item primary_text="{{initData.alternateContactLabel + this.implEAddressType.eAddressType}}"
secondary_text="{{this.value}}"
cta="{text: '{{initData.uxButtonChangeLabel}}', onclick: 'alternateContactClick:{{index}},{{this.implEAddressType.eAddressType}}'}"
ariaLabel="{{initData.uxButtonChangeLabel}} {{initData.alternateContactLabelPH}}">
</ux-list-item>
In JSON I have:
"initData": {
"alternateContactLabelM":"Alternative Mobile Number (SMS)",
"alternateContactLabelE":"Alternative Email Address",
"alternateContactLabelPH":"Alternative Contact Number",
"alternateContactLabelFX":"Alternative Fax",
}

You will need to use a combination of a custom helper to produce the name of the key and the built-in lookup helper to get the value of that property on the initData object.
Handlebars helpers for string concatentation have doubtlessly been written before, but I will write my own simple implementation here:
Handlebars.registerHelper('concat', function () {
return Array.prototype.slice.call(arguments, 0, -1).join('');
});
This helper concatenates all of the parameters passed to it except for the last parameter, which we know is the Handlebars options object.
We can now use this helper in our template to dynamically return the key name. We will then use the lookup helper to find the value of initData at that key:
primary_text="{{lookup initData (concat 'alternateContactLabel' implEAddressType.eAddressType)}}"
For a working example, please see this fiddle.

Related

How do I get information about function calls from a Lua script?

I have a script written in Lua 5.1 that imports third-party module and calls some functions from it. I would like to get a list of function calls from a module with their arguments (when they are known before execution).
So, I need to write another script which takes the source code of my first script, parses it, and extracts information from its code.
Consider the minimal example.
I have the following module:
local mod = {}
function mod.foo(a, ...)
print(a, ...)
end
return mod
And the following driver code:
local M = require "mod"
M.foo('a', 1)
M.foo('b')
What is the better way to retrieve the data with the "use" occurrences of the M.foo function?
Ideally, I would like to get the information with the name of the function being called and the values of its arguments. From the example code above, it would be enough to get the mapping like this: {'foo': [('a', 1), ('b')]}.
I'm not sure if Lua has functions for reflection to retrieve this information. So probably I'll need to use one of the existing parsers for Lua to get the complete AST and find the function calls I'm interested in.
Any other suggestions?
If you can not modify the files, you can read the files into a strings then parse mod file and find all functions in it, then use that information to parse the target file for all uses of the mod library
functions = {}
for func in modFile:gmatch("function mod%.(%w+)") do
functions[func] = {}
end
for func, call in targetFile:gmatch("M%.(%w+)%(([^%)]+)%)") do
args = {}
for arg in string.gmatch(call, "([^,]+)") do
table.insert(args, arg)
end
table.insert(functions[func], args)
end
Resulting table can then be serialized
['foo'] = {{"'a'", " 1"}, {"'b'"}}
3 possible gotchas:
M is not a very unique name and could vary possibly match unintended function calls to another library.
This example does not handle if there is a function call made inside the arg list. e.g. myfunc(getStuff(), true)
The resulting table does not know the typing of the args so they are all save as strings representations.
If modifying the target file is an option you can create a wrapper around your required module
function log(mod)
local calls = {}
local wrapper = {
__index = function(_, k)
if mod[k] then
return function(...)
calls[k] = calls[k] or {}
table.insert(calls[k], {...})
return mod[k](...)
end
end
end,
}
return setmetatable({},wrapper), calls
end
then you use this function like so.
local M, calls = log(require("mod"))
M.foo('a', 1)
M.foo('b')
If your module is not just functions you would need to handle that in the wrapper, this wrapper assumes all indexes are a function.
after all your calls you can serialize the calls table to get the history of all the calls made. For the example code the table looks like
{
['foo'] = {{'a', 1}, {'b'}}
}

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' -->

Kotlin function reference

Let records be stream/collection and extract function which transforms data form an element of such collection.
Is there a way in Kotlin to write
records.map {extract(it)}
without explicitely applying(it) ?
E.g. records.map(extract) or records.map {extract}
If extract is a value (local variable, property, parameter) of a functional type (T) -> R or T.() -> R for some T and R, then you can pass it directly to map:
records.map(extract)
Example:
val upperCaseReverse: (String) -> String = { it.toUpperCase().reversed() }
listOf("abc", "xyz").map(upperCaseReverse) // [CBA, ZYX]
If extract is a top-level single argument function or a local single argument function, you can make a function reference as ::extract and pass it to map:
records.map(::extract)
Example:
fun rotate(s: String) = s.drop(1) + s.first()
listOf("abc", "xyz").map(::rotate) // [bca, yzx]
If it is a member or an extension function of a class SomeClass accepting no arguments or a property of SomeClass, you can use it as SomeClass::extract. In this case, records should contain items of SomeType, which will be used as a receiver for extract.
records.map(SomeClass::extract)
Example:
fun Int.rem2() = this % 2
listOf("abc", "defg").map(String::length).map(Int::rem2) // [1, 0]
Since Kotlin 1.1, if extract is a member or an extension function of a class SomeClass accepting one argument, you can make a bound callable reference with some receiver foo:
records.map(foo::extract)
records.map(this::extract) // to call on `this` receiver
Example:
listOf("abc", "xyz").map("prefix"::plus) // [prefixabc, prefixxyz]
(runnable demo with all the code samples above)
you could use method reference (similar to Java).
records.map {::extract}
take a look at the function references examples on kotlin docs
https://kotlinlang.org/docs/reference/reflection.html#function-references

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";
}

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);
});

Resources