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' -->
Related
I have a for loop and want to filter some nodes, which works fine:
matches($doc/abc/#def, $filterA)
matches($doc/qwert/#xyz, $filterB)
What also works is, when $filterA, $filterB or both are empty, to return every node. What does not work however is to return the node if node abc or qwert do not exist. For the default value i currently use "" (empty string), is there another default value or another function I can use to make it work?
You can test whether the abc and qwert elements exist with the fn:exists() function. If you want it to pass if either of those elements do not exist, you can use fn:not() to negate a test for abc and qwert existence:
fn:not(fn:exists($doc/abc) and fn:exists($doc/qwert))
If you want a condition to pass if either $filterA or $filterB is empty:
fn:not(fn:exists($filterA) and fn:exists($filterB))
You can consolidate the matches() expressions a predicate to avoid repeating $doc (not a huge savings, but something to think of more generally when writing XPath expressions.
$doc[matches(abc/#def, $filterA) and matches(qwert/#xyz, $filterB)]
Putting it all together:
let $filterA := "a"
let $filterB :="b"
let $doc := <doc><abc def="a"/><qwert xyz="b"/></doc>
return
if (fn:not(fn:exists($doc/abc) and fn:exists($doc/qwert))
or fn:not(fn:exists($filterA) and fn:exists($filterB))
or $doc[matches(abc/#def, $filterA) and matches(qwert/#xyz, $filterB)])
then "pass - copy nodes"
else "fail"
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.
I'm trying to use the update_item functionality for DynamoDB in boto3.
I'm struggling right now to update lists for items. I would like to create a new list if the list does not exist yet and otherwise append to the existing list.
Using an UpdateExpression of the form SET my_list = list_append(my_list, :my_value) returns an error "The provided expression refers to an attribute that does not exist in the item" if the list does not exist yet.
Any idea how I would have to modify my UpdateExpression?
You can use list_append(if_not_exists()) construction.
UpdateExpression:
'SET my_list2 = list_append(if_not_exists(my_list2, :empty_list), :my_value)'
ExpressionAttributeValues:
{ ":my_value":{"L": [{"S":"test"}]}, ":empty_list":{"L":[]} }
Update: as mentioned in the comments, boto3 now raises an error for the expression above and a version without explicit types works: { ":my_value": ["test"], ":empty_list":[] }.
An alternative to Boris solution could be to use set instead of list datatype and use the ADD keyword, it does exactly what you want.
With Add, the update expression becomes: ADD setName :s
And the expression attribute values can be like: {":s": {"SS":["First", "Second"]}}
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.ADD
I am trying to create an empty map, that will be then populated within a for loop. Not sure how to proceed in Rascal. For testing purpose, I tried:
rascal>map[int, list[int]] x;
ok
Though, when I try to populate "x" using:
rascal>x += (1, [1,2,3])
>>>>>>>;
>>>>>>>;
^ Parse error here
I got a parse error.
To start, it would be best to assign it an initial value. You don't have to do this at the console, but this is required if you declare the variable inside a script. Also, if you are going to use +=, it has to already have an assigned value.
rascal>map[int,list[int]] x = ( );
map[int, list[int]]: ()
Then, when you are adding items into the map, the key and the value are separated by a :, not by a ,, so you want something like this instead:
rascal>x += ( 1 : [1,2,3]);
map[int, list[int]]: (1:[1,2,3])
rascal>x[1];
list[int]: [1,2,3]
An easier way to do this is to use similar notation to the lookup shown just above:
rascal>x[1] = [1,2,3];
map[int, list[int]]: (1:[1,2,3])
Generally, if you are just setting the value for one key, or are assigning keys inside a loop, x[key] = value is better, += is better if you are adding two existing maps together and saving the result into one of them.
I also like this solution sometimes, where you instead of joining maps just update the value of a certain key:
m = ();
for (...whatever...) {
m[key]?[] += [1,2,3];
}
In this code, when the key is not yet present in the map, then it starts with the [] empty list and then concatenates [1,2,3] to it, or if the key is present already, let's say it's already at [1,2,3], then this will create [1,2,3,1,2,3] at the specific key in the map.
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);
});