Search code examples
javaspring-bootthymeleaf

Thymeleaf - skip table creation if the iterated list is null


I have an html thymeleaf template where I build a table iterating over a list:

    <table>
        <tr>
            <th>Setup Name</th>
            <th>Setup Path</th>
        </tr>
        <tr th:each="setup : ${upgradeState.targetUpgradeSetups.setups}">
            <td th:text="${setup.name}"/>
            <td th:text="${setup.path}"/>
        </tr>
    </table>

The problem is that the element upgradeState.targetUpgradeSetups may be null, so I would like to build this table only when the element is not null.

Note: if the element upgradeState.targetUpgradeSetups is not null, then it's guaranteed for the list setups to be not null either. Hence I only need to check for the parent element.

I have tried to use the th:if statement as follows:

<tr th:if=${upgradeState.targetUpgradeSetups != null} th:each="setup : ${upgradeState.targetUpgradeSetups.setups}">

But even like that, I still get the same exception:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'setups' cannot be found on null
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:213)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:51)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:406)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:90)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:109)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:328)
    at org.thymeleaf.spring5.expression.SPELVariableExpressionEvaluator.evaluate(SPELVariableExpressionEvaluator.java:263)
    ... 74 more

I didn't manage to find a specific example/reference about Thymeleaf for such issue, could anyone please suggest the right way?


Solution

  • You need to count on Thymeleaf Attribute Precedence. According to the order, Thymeleaf will parse iteration first and only after the condition, when placed into the same tag. The code which would work for you may look like ...

    <table>
        <tr>
            <th>Setup Name</th>
            <th>Setup Path</th>
        </tr>
        <tbody th:if=${upgradeState.targetUpgradeSetups != null}>
        <tr th:each="setup : ${upgradeState.targetUpgradeSetups.setups}">
            <td th:text="${setup.name}"/>
            <td th:text="${setup.path}"/>
        </tr>
        </tbody>
    </table>