Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThymeLeaf Fragment executed on false th:if

I'm using Thymeleaf packaged with Spring-Boot. Here is the main template:

<div class="container">
    <table th:replace="fragments/resultTable" th:if="${results}">
        <tr>
            <th>Talent</th>
            <th>Score</th>
        </tr>
        <tr>
            <td>Confidence</td>
            <td>1.0</td>
        </tr>
    </table>
</div>

And it uses this fragment:

<table th:fragment="resultTable">
    <tr>
        <th>Talent</th>
        <th>Score</th>
    </tr>
    <tr th:each="talent : ${talents}">
        <td th:text="${talent}">Talent</td>
        <td th:text="${results.getScore(talent)}">1.0</td>
    </tr>
</table>

The fragment only works if there is a results object. That makes sense to me. So based on the syntax from the documentation I added the th:if statement to the main template file. However I'm still getting this error when I access the template without an object

Attempted to call method getScore(com.model.Talent) on null context object

Shouldn't the th:if statement prevent that code from being accessed?

The template still works fine when the results object is populated, but how do I get the null case to render without the table?

like image 856
GridDragon Avatar asked Dec 13 '16 19:12

GridDragon


People also ask

How do you use Thymeleaf fragments?

There are three basic ways to include content from a fragment: insert – inserts content inside the tag. replace – replaces the current tag with the tag defining the fragment. include – this is deprecated but it may still appear in a legacy code.

How do you replace Thymeleaf th?

Basic inclusion with th:insert and th:replace Thymeleaf can include parts of other pages as fragments (whereas JSP only includes complete pages) using th:insert (it will simply insert the specified fragment as the body of its host tag) or th:replace (will actually substitute the host tag by the fragment's).

Is Thymeleaf fully integrated with Spring?

It provides full integration with Spring Framework. It applies a set of transformations to template files in order to display data or text produced by the application. It is appropriate for serving XHTML/HTML5 in web applications. The goal of Thymeleaf is to provide a stylish and well-formed way of creating templates.


2 Answers

Fragment inclusion has a higher operator precedence than th:if.

http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#attribute-precedence

You'll probably have to move the th:if to a tag above. Either in the container div, or if you still need the container div, then a th:block like this:

<div class="container">
    <th:block th:if="${results}">
        <table th:replace="fragments/resultTable">
            <tr>
                <th>Talent</th>
                <th>Score</th>
            </tr>
            <tr>
                <td>Confidence</td>
                <td>1.0</td>
            </tr>
        </table>
    </th:block>
</div>
like image 93
Metroids Avatar answered Nov 03 '22 16:11

Metroids


With Thymeleaf 3.0 you can use the no-operation token to insert/replace only if condition is met, something like this:

<table th:replace="${results} ? ~{fragments :: resultTable} : _">

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#advanced-conditional-insertion-of-fragments

like image 23
klorand Avatar answered Nov 03 '22 18:11

klorand