Thymeleaf
th:each
th:if
Java
HTML templating

Thymeleaf theach filtered with thif

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Thymeleaf, th:each iterates collections and th:if conditionally renders elements. Combining them is common, but mixing filtering logic in templates can become hard to maintain if conditions grow complex.

This article shows clean patterns for filtering rendered items with th:if and alternatives for better separation of concerns.

Core Sections

1) Basic combination of th:each and th:if

html
<tr th:each="user : ${users}" th:if="${user.active}">
  <td th:text="${user.name}"></td>
</tr>

Only active users render.

2) Use th:if inside loop body

html
1<tr th:each="order : ${orders}">
2  <td th:text="${order.id}"></td>
3  <td th:if="${order.total > 100}" th:text="'High value'"></td>
4</tr>

This keeps row iteration intact while conditionally showing cells.

3) Pre-filter in controller/service (preferred)

java
1List<User> activeUsers = users.stream()
2    .filter(User::isActive)
3    .toList();
4model.addAttribute("users", activeUsers);

Templates remain simpler and more readable.

4) Avoid heavy logic in expressions

Complex expression chains inside templates reduce maintainability and testability.

5) Use th:unless when clearer

html
<span th:unless="${item.available}">Out of stock</span>

Pick whichever improves readability for the condition.

6) Production checklist for Thymeleaf conditional iteration

Code examples are necessary, but production readiness depends on how this pattern behaves under failure, load, and operational drift. Before rollout, define success criteria that are measurable. A useful baseline is three metrics: correctness (for example, expected output match rate), reliability (error rate and retry behavior), and latency (p95 or p99 execution time). Capture these metrics in a repeatable test environment rather than relying on ad hoc local runs. If external systems are involved, include at least one synthetic fault scenario such as timeout, malformed payload, or temporary dependency outage. This confirms the implementation fails predictably and recovers in a controlled way.

Document environment assumptions close to the code. Include runtime version constraints, required environment variables, and exact dependency versions used during validation. Many regressions come from mismatched environments rather than algorithmic changes. A short README snippet or inline comment that names these assumptions can prevent repeated troubleshooting later. Also define ownership for operational issues: who receives alerts, what threshold triggers action, and what rollback path is acceptable. Without explicit ownership and rollback criteria, otherwise small incidents can take longer to resolve.

A practical rollout sequence is:

  1. Run automated checks (lint, unit tests, static validation) in CI.
  2. Execute a smoke test against representative input sizes.
  3. Validate one failure mode and verify error visibility in logs.
  4. Deploy behind a feature flag or phased rollout if possible.
  5. Monitor key metrics for a defined stabilization window.
bash
1# Example operator workflow
2make lint
3make test
4./scripts/smoke_check.sh

Finally, keep a short limitations section. State what the current approach intentionally does not optimize or support. This prevents accidental misuse by future contributors and keeps design discussions grounded in explicit tradeoffs. For long-lived systems, schedule periodic review of this implementation, especially after runtime upgrades or library changes. A lightweight maintenance cadence often catches compatibility issues before they become production incidents.

Common Pitfalls

  • Embedding complex business logic directly in template expressions.
  • Applying th:if at wrong element level and breaking table/list layout.
  • Repeating same filter condition across multiple template fragments.
  • Ignoring controller-level pre-filtering opportunities.
  • Mixing null-unsafe expressions and causing rendering errors.

Summary

th:each plus th:if is valid and useful for simple rendering conditions. For maintainable views, keep templates declarative and move complex filtering to controller/service layers. This balances flexibility with readability.

A short maintenance note should accompany this implementation in your repository docs so future contributors know expected behavior, validation steps, and rollback options. That small documentation investment usually prevents repeat regressions during dependency upgrades, framework changes, and environment migrations.

Include one template rendering test in CI that verifies filtered rows for both matching and non-matching conditions so expression regressions are caught early.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.