How to loop through Map in Thymeleaf

January 04, 2020 No comments Thymeleaf Map Loop

1. Introduction

This article describes how to iterate over each element in Map object in Thymeleaf.

For more information about how iterators works and how to configure Thymeleaf with Spring Boot please check below links: Spring Boot with Thymeleaf
Using th:each in Thymeleaf

2. Using th:each attribute on Maps

Thymeleaf is flexible in many ways. When it comes to interations, you can use not only java.util.List objects but also any other collection that implements java.util.Iterable or java.util.Enumeration or java.util.Iterator or java.util.Map interface. We can simply use th:each in our case, to loop through Map. Note that the iteration variable will be of class java.util.Map.Entry.

Let's start our example with a simple model that presents the Car:

package com.frontbackend.thymeleaf.model;

import lombok.Builder;
import lombok.Getter;

import java.util.Date;

@Getter
@Builder
public class Car {

    private String vin;
    private Color color;
    private String model;
    private Date productionDate;
}

The color will be a simple enum of three values: RED, WHITE, BLACK.

package com.frontbackend.thymeleaf.model;

public enum Color {

    RED,
    WHITE,
    BLACK
}

The controller class provides two maps:

  • with cars grouped by the color,
  • with cars grouped by production year.
@GetMapping("/")
    public String getMap(Model model) throws ParseException {
        model.addAttribute("carsByColor", carService.randomCars()
                                                    .stream()
                                                    .collect(Collectors.groupingBy(Car::getColor)));

        model.addAttribute("carsByProductionYear", carService.randomCars()
                                                             .stream()
                                                             .collect(Collectors.groupingBy(
                                                                     car -> yearFormatter.format(
                                                                             car.getProductionDate()))));
        return "maps";
    }

Thymeleaf template that iterates over those two Maps will have the following structure:

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Spring Boot Thymeleaf Application - Iteration over Map</title>
</head>
<body>

<h1>Cars by color</h1>
<table>
    <tr>
        <th>No</th>
        <th>Color</th>
        <th>Cars</th>
    </tr>
    <tr th:each="entry, stat : ${carsByColor}">
        <td th:text="${stat.index + 1}">1</td>
        <td th:text="${entry.key}">color</td>
        <td>
            <table>
                <tr th:each="car : ${entry.value}">
                    <td th:text="${car.vin}"></td>
                    <td th:text="${car.model}"></td>
                    <td th:text="${#dates.format(car.productionDate, 'yyyy-MM-dd')}"></td>
                </tr>
            </table>
        </td>
    </tr>
</table>


<h1>Cars by production year</h1>
<table>
    <tr>
        <th>No</th>
        <th>Year</th>
        <th>Cars</th>
    </tr>
    <tr th:each="entry, stat : ${carsByProductionYear}">
        <td th:text="${stat.index + 1}">1</td>
        <td th:text="${entry.key}">production year</td>
        <td>
            <table>
                <tr th:each="car : ${entry.value}">
                    <td th:text="${car.vin}"></td>
                    <td th:text="${car.model}"></td>
                    <td th:text="${car.color}"></td>
                    <td th:text="${#dates.format(car.productionDate, 'yyyy-MM-dd')}"></td>
                </tr>
            </table>
        </td>
    </tr>
</table>

</body>
</html>

Note that in our case ${entry.value} will point to the collection of specific Car objects grouped by provided attribute.

3. Conclusion

In this tutorial, we showcased the simple example of how to loop through Map in Thymeleaf. We use a map when a key is a color or a year of production and the value is a collection of aggregated cars.

This code can be found in our GitHub repository.

{{ message }}

{{ 'Comments are closed.' | trans }}