How to check for an empty Map in a Soy template? - google-closure-templates

I've read the docs for Google Soy/Closure templates, but can't find any way to check whether a Map is empty; I can only look up the map's value for a given key. Is there a way to find out the size of a Map?
My current workaround is to replace any empty maps with null and then check for null in the template, e.g.:
{if $myMap}
<!-- Do something that requires a non-empty map -->
{/if}

You can get the keys of the map using the keys function, and then use length on that, so this should work:
{if length(keys($myMap)) == 0}
...
{/if}

Related

Why should I use key as string for list item in React?

React Doc explains why giving a key to list item is important. It specifies that a key is string attribute.
So should I convert my id to string for key every time?
<ul>
{data.map(item => (
<li key={item.id.toString()}>
{item.text}
</li>
</ul>
Could you tell me the reason for this? I thought about problem with number sort as strings but it seemed to be another case.
React Doc. List and Keys
Key is fundamental for the React to index a list in the render process (in the background). If you don't put the key, you get this:
This simply means that he needs to look for the component, what will take longer.
To solve the toString(), to this:
key={`OperationTesterInput_${idx}`
Looks much more cleaner. You can also use the index parameter present in the map function, also does the trick :)
The Reason why its a string
It is not. The reason is because of typescript. The implementation is the following:
So following this implementation, this is valid:
Generally, Key is used so that if an element changes or is removed, React only needs to rerender that specific element rather than the whole list. This key is required to be a string because the HTML attribute values are always strings, whatever value you give must be serialized to a string. We can assign anything to an attribute, but it becomes a string.

Get attribute of specific index object

I am trying to iterate through two array in my view in Angular2. I iterate through my first array using *ngFor and I use the index to iterate through the second one. The problem is, I can't get the attribute of an object of the second array, it's just bug everything.
<tr *ngFor="let round of rounds ; let i = index">
<td>{{customers[i].login}}</td>
<td>{{round.status}}</td>
</tr>
Here, the customers[i].login doesn't work. But if instead I put only customers[i] I'll see in my view that I have [object Object].
How can I access the attribute of my customer object, or how can I iterate through the two array at the same time in a better way ?
customers[i]?.login
You can use the ?. accessor in order to prevent the error from happening.
The accessor variant of the existential operator ?. can be used to
soak up null references in a chain of properties. Use it instead of
the dot accessor . in cases where the base value may be null or
undefined.

In XDocReport, how to handle null value?

Is there a way to handle null value for a field in XDocReport? or do I need to manipulate it on my own? example:
if (thisVar == null)
context.put("sampleText", "");
else
context.put("sampleText", thisVar);
or is there an option in docx quick parts?
I found this line in the error message of XDocReport. However I could not understand where to apply this, in the template or in the code.
Tip: If the failing expression is known to be legally refer to
something that's sometimes null or missing, either specify a default
value like myOptionalVar!myDefault, or use [#if
myOptionalVar??]when-present[#else]when-missing[/#if]. (These only
cover the last step of the expression; to cover the whole expression,
use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
In docx, append ?if_exists to the field name
«${tx.amount?if_exists}»
you may also append !
«${tx.amount!}»
Please refer to this link for those who uses freemarker. How to check if a variable exists in a FreeMarker template?

applying class in ng-repeat if contained in another array

I am querying for a collection of IDs from Parse.com and showing them in my $scope as an array.
I would like to apply a class to the items in my $scope that match any one of these IDs, placing a border around the object illustrating that it is already contained in the 'saved' array. I have tried the following however not having any luck.
ng-class="{'approved': ParseSavedExercises.indexOf(exercise.id) == -1}"
in this case my ParseSavedExercisesis my array to check against and exercise.id is what I am checking for.
here is a quick fiddle
Please see here http://jsfiddle.net/e9pr4yqj/
Yours ParseSavedExercises contains string and id is number so no id existed in ParseSavedExercises
$scope.ParseSavedExercises = ['2','3'];
change to
$scope.ParseSavedExercises = [2,3];
or use
ng-class="{'approved': ParseSavedExercises.indexOf(exercise.id.toString()) == -1}"
like here http://jsfiddle.net/1ujgvL80/

How to convert <node/> to <node></node> with libxml (converting empty elements to start-end tag pairs)

While generating an XML content, I get an empty node <node/>, and I want it to be <node></node>. (Since <node></node> is the correct form of c14n, the progress called "converting empty elements to start-end tag pairs")
How should I convert it?
There's a way hinted by Jim Garrison(Thank you) to do this,
by using xmlBufferCreate, xmlSaveToBuffer, xmlSaveDoc, xmlSaveClose
with xmlSaveOption: XML_SAVE_NO_EMPTY
Take a look at the libxml2 documentation, specifically xmlSaveOption value XML_SAVE_NO_EMPTY
I found another way which is easier when the nodes are generated under control, by simply giving value "" to the node.

Resources