Andre Ellis
Andre Ellis

Reputation: 13

Thymeleaf th:each repair

I am trying to use the th:each function for my site, to find all the dogs in my database, and am using the following code. In my controller, I have:

@Controller
public class DogController {

private DogDatabase database = new DogDatabase();
@RequestMapping(value = "/allDogs", method = RequestMethod.GET)
public String getAllDogs(Model model)
{
    ArrayList<Integer> ids = database.getAllIDs();
    System.out.println(ids.size());
    Dog[] dogs = new Dog[ids.size()+1];

    for(int i = 0; i < ids.size(); ++i)
    {
        dogs[i] = database.getDog(ids.get(i));
    }
    model.addAttribute("dogs", dogs);

    return "getAllDogs";
}

After this for loop, I did a println on each object in the array and verified, that all my dog objects are valid and not null. After verifying that the array is correct, I am passing it as a model and trying to get it in the html. The current problem is that when I go to the html, it displays nothing. I'm not getting any thymeleaf errors, just a blank screen. Attached is my html code where I call th:each

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>All Dogs</title>
</head>

<body>
    <table>
        <th:block th:each="dog : ${dogs}">
            <tr>
                <td>Name: </td>
                <td th:text="${dog.name}">Name</td>
            </tr>
        </th:block>
    </table>
</body>
</html>

Edit One and Two: edit was to fix errors, that was not in my code

Edit Three: I tried switching dog and dogs in the iterator (as in code above,) but now I am getting an error that there was an "Exception evaluating SpringEL expression: "dog.name" (template: "getAllDogs" - line 13, col 21)"

This does not make sense, however, as I use dog.name throughout the site, and getName() is public in Dog class. Upon request, I am adding my dog class: https://pastebin.com/Lknc8dtZ

Upvotes: 0

Views: 1786

Answers (2)

Metroids
Metroids

Reputation: 20487

There is no reason here to use an array of Dog[] rather than a List<Dog> -- and that is probably what is causing your error. You are creating an array that is too big, and so it's trying to call getName() on a null object.

@RequestMapping(value = "/allDogs", method = RequestMethod.GET)
public String getAllDogs(Map<String, Object> model) {
    List<Dog> dogs = database.getAllIDs()
            .stream()
            .map(id -> database.getDog(id))
            .collect(Collectors.toList());
    model.put("dogs", dogs);
    return "getAllDogs";
}

Also, you have don't need the extra <th:block />. You can move the th:each directly onto the <tr>.

<table>
    <tr th:each="dog : ${dogs}">
        <td>Name: </td>
        <td th:text="${dog.name}">Name</td>
    </tr>
</table>

Upvotes: 1

Nacho Zve De La Torre
Nacho Zve De La Torre

Reputation: 364

I believe the problem is here:

<th:block th:each="dogs : ${dog}">

sience in your controller you are binding the Dog[] array to the variable "dogs":

model.addAttribute("dogs", dogs);

So in your template you should iterate like this:

<th:block th:each="dog : ${dogs}">
            <tr>
                <td>Name: </td>
                <td th:text="${dog.name}">Name</td>
            </tr>
</th:block>

to look for each dog in the dogs array :)

Upvotes: 4

Related Questions