Spring / Thymeleaf: Property or field 'title' cannot be found on null. Why?

3.2k Views Asked by At

The application throws org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'title' cannot be found on null

and I can't understand why... Here is the html snippet, called by the master.

<title th:fragment="title">Surveys Feed</title>
<div th:fragment="content" th:each="surv : ${allSurveys}" >
    <div id="surv-ct" style="min-width: 310px; max-width: 800px;     height:400px; margin: 0 auto">
    <script th:inline="javascript">
       /*<![CDATA[*/
           $('#surv-ct').highcharts({
               chart: {
                   type: 'bar'
               },
               title: {
                   text: [[${surv.title}]]
               },
             // ... other stuff 
    </script>
  </div>
</div>

Yet when the application is launched, the field title isn't null! Here we have the mapping fot the object allSurveys, which takes all the surveys from the repo and returns a list.

@ModelAttribute("allSurveys")
public List<Survey> allSurveys() {
    List<Survey> surveys = new Surveys(repo.findAll()).getSurveys();
    // print surveys titles
    for (int i = 0; i < surveys.size(); i++) {
        Survey sur = surveys.get(i);
        System.out.println("Survey info: " + sur.getTitle());
    }
    return surveys;
}

As proof we can see that the surveys' titles are printed on the console: Console output

And they are PRESENT in the database Surveys Database

So why does it say that is null? I have seen different answers on the internet but none seems to be a solution for my case.

Thank you in advance for your help.

EDIT: On suggestion I tried to print the object ${surv}. I changed the "surv-ct" attribute of the inner div from ID to class since they are supposed many.

<div th:fragment="content" th:each="surv : ${allSurveys}" >
    <div class="surv-ct" style="min-width: 310px; max-width: 800px; height: 400px; margin: 0 auto">
        <p>Object is: <span th:text=${surv}>obj</span></p>
        <!--
        <script th:inline="javascript">
           /*<![CDATA[*/

               $('.surv-ct').highcharts({
                   chart: {
                       type: 'bar'
                   },
                   // ... more code
    -->
    </div>
</div>

When I analize the code on Mozilla, this is the result.

    <p>Object is: <span></span></p>
    <!--
    <script th:inline="javascript">
       /*<![CDATA[*/
           $('.surv-ct').highcharts({
                // ... more code that i deleted
                // it's commented anyway
      -->

First of all, only one result is printed. And secondly it doesn't get any surv object. That's why the field "title" is null I guess. So why is the object null then? Any suggestion?

1

There are 1 best solutions below

0
Andrew On

I suspect this is because you're using th:include when you're using the fragment. According to the Thymeleaf Documentation:

Whereas th:include will include the contents of the fragment into its host tag, th:replace will actually substitute the host tag by the fragment’s

This means your th:each will just be ignored - explaining why you're only seeing the one result printed.

The solution is to use th:replace, which will make use of the th:if. Or you can change the format of your fragment slightly, so that the th:each is part of the fragment content. eg:

<th:block th:fragment="content">
    <div th:each="surv : ${allSurveys}">
        <div id="surv-ct" style="min-width: 310px; max-width: 800px;     height:400px; margin: 0 auto">
            <script th:inline="javascript">
               /*<![CDATA[*/
                   $('#surv-ct').highcharts({
                       chart: {
                           type: 'bar'
                       },
                       title: {
                           text: [[${surv.title}]]
                       },
                     // ... other stuff 
            </script>
        </div>
    </div>
</th:block>