2

Newbie to AEM here. Say I have:

<div
     data-text="${myVariable.someProperty}"
     ...

I do not wish to have data-text to return a "undefined" string if it is undefined. I tried using the logical operator and it didn't work..

<div
     data-text="${myVariable.someProperty ? myVariable.someProperty : ''}"

I supposed that myVariable.someProperty returns undefined instead of a boolean value. Any ideas how I can check for undefined in HTL (or am I doing something completely wrong)?

夢のの夢
  • 5,054
  • 7
  • 33
  • 63
  • you can try this myVariable.someProperty == 'undefined' ? '' : myVariable.someProperty – karthick Feb 13 '18 at 03:35
  • Do you want to have `data-text` attribute but with empty string value? Sightly removes the attributes with blank value from markup. Also if you can add details about `myVariable` is that being returned from JS or Java use API? – Sandeep Kumar Feb 13 '18 at 04:03
  • Where and how is that property set? HTL expressions do not output anything for undefined values. Having `undefined` rendered indicates that the property was already set to the `"undefined"` string value. – Vlad Feb 13 '18 at 08:09

5 Answers5

1

According to the HTL documentation

... operators are typically used with Boolean values, however, like in JavaScript, they actually return the value of one of the specified operands, so when used with non-Boolean values, they may return a non-Boolean value

If a value can be converted to false, the value is so-called falsy. Values that can be converted to false are: undefined variables, null values, the number zero, and empty strings.

Conforming to it, data-sly-test="${myVariable.someProperty == true}" should do the job.

iusting
  • 7,850
  • 2
  • 22
  • 30
1

HTL will not render anything for undefined values. Assuming an JS use-object:

logic.js:

use(function () {
    return {
        test: undefined
    };
});

and an HTL script:

<div data-sly-use.logic="logic.js" data-text="${logic.test}"></div>

the output will be:

<div></div>

The attribute is stripped as it is falsy (see attributes detailed examples). If you want to keep the attribute you might want to modify the HTL expression to ${logic.test || true}.

If you modify your use-object to return an 'undefined' string:

use(function () {
    return {
        test: 'undefined'
    };
});

then you get the following output:

<div data-text="undefined"></div>

In this case you might want to modify your expression to test for the 'undefined' string: ${logic.test == 'undefined' ? '': logic.test}. Again, you can keep the attribute by replacing '' with true.

Vlad
  • 10,602
  • 2
  • 36
  • 38
0

Besides the other provided solutions there is another way to achieve something like this, even though it might seem a bit counter intuitive and verbose:

<!-- Only show this div if "someProperty" is set -->
<div data-text="${myVariable.someProperty}" 
     data-sly-test.hasValue="${myVariable.someProperty}">

<!-- Show alternative div if "someProperty" is not set -->
<div data-text="No value defined" data-sly-test="!hasValue">

The code above is basically a if - else statement. Only one of the div elements will be displayed. Which one depends on somePropertybeing set or not.

Note that the result of data-sly-test is stored in hasValue so that test does not have to be repeated for the second div.

Jens
  • 20,533
  • 11
  • 60
  • 86
0

Above solution from jens is correct but there is a syntax error in the usage of hasValue variable.

<div data-text="No value defined" data-sly-test="${!hasValue}">
Jithin Kumar
  • 49
  • 1
  • 9
0

data-sly-test="${myVariable.someProperty !=null}" as simple as that can do the job. It checks if the property is present and returns "true" or "false"