I made a modal in my Bootstrap 4 view. But I get an error
ERROR 328 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringInputGeneralFieldTagProcessor' (template: "admin" - line 87, col 78)] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153) ~[spring-webmvc-6.0.7.jar:6.0.7]
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:926) ~[spring-webmvc-6.0.7.jar:6.0.7]
Here's a code snippet from my HTML view. I left a comment to show you which line causes an error
<tbody>
<!-- remember this user object below, I'll be referencing it later -->
<tr th:each="user: ${users}">
<td th:text="${user.username}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.lastName}"></td>
<td th:text="${user.department}"></td>
<td th:text="${user.salary}"></td>
<td th:text="${user.age}"></td>
<td th:text="${user.email}"></td>
<td>
<span th:each="role, iter : ${user.authorities}"
th:text="${role.authority == 'USER' ? 'U' : (role.authority == 'ADMIN' ? 'A' : '')} + ${iter.last ? '' : ' '}"></span>
</td>
<td th:text="${user.isEnabled() ? '+' : '-'}"></td>
<td class="btn-group btn-group-sm">
<a class="btn btn-outline-primary" data-toggle="modal" th:data-target="${'#updateModal' + user.username}">Update</a>
<div class="modal" th:id="${'updateModal' + user.username}">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" th:text="${'Edit ' + user.name + ' ' + user.lastName + ' (' + user.username + ')'}"></h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<p th:text="'For the sake of privacy, you are only allowed to change the user\'s department ' +
'and salary. If you think ' + ${user.name} + '\'s personal info needs to be altered, please request them to do so'"></p>
<!-- I also tried removing this th:object altogether ↓-->
<form th:action="@{/save-user}" th:object="${user}" method="post">
<!-- below is line 87 that causes an error. the user I try to reference here is the same user from th:each="user: ${users} in the code above -->
<input type="hidden" th:field="${user.id}">
<input type="hidden" th:field="${user.username}">
<input type="hidden" th:field="${user.password}">
<input type="hidden" th:field="${user.name}">
<input type="hidden" th:field="${user.lastName}">
<fieldset>
<label for="departments">Department: </label>
<select id="departments" th:field="${user.department}">
<option th:value="accounting">Accounting</option>
<option th:value="sales">Sales</option>
<option th:value="'information technology'">IT</option>
<option th:value="'human resources'">HR</option>
</select>
</fieldset>
<fieldset>
<label for="salary">Salary: </label>
<input id="salary" th:field="${user.salary}"/>
</fieldset>
<input type="hidden" th:field="${user.age}">
<input type="hidden" th:field="${user.email}">
<input type="hidden" th:field="${user.enabledByte}">
<input type="hidden" th:name="authorities"
th:value="${#strings.toString(user.authorities)}"/>
<input class="main-button" type="submit" value="Submit">
</form>
</div>
</div>
</div>
</div>
For some reason, at line 87, Thymeleaf seemingly can't access that forEach user's fields anymore even though it's within the scope – the <tr>
element that has the th:each
attribute. Could you please tell me why that's so and how I can fix it?
The controller looks like this. As you see, there are no other attributes there that have the same name ("user")
@GetMapping("/admin")
public String admin(Model model, Authentication authentication) {
model.addAttribute("users", service.getAllExceptLoggedUser(authentication))
.addAttribute("loggedUser", service.getLoggedUser(authentication))
.addAttribute("newUser", new User())
.addAttribute("adminRoleSet", service.getAdminRoleSet());
return "admin";
}
Also, the IDE doesn't underline "user" anywhere in my view code so it apparently knows what user I'm talking about
I read these StackOverflow questions: 1, 2, 3, 4. They don't seem to have much to do with my question although they refer to the same error message
UPD: For some reason, changing, for example, this
<input type="hidden" th:field="${user.id}">
to this
<input type="hidden" name="id" th:value="${user.id}">
helped. It seems so anyway, I haven't properly tested it yet. At least, I am now able to see the view, the modals pop up. Feel free to share your ideas on what that "some" reason might be in the comments (or even write a full-fledged answer)
Though there's one but. I hoped a user's current department will be selected in the drop-down list. Instead, it's simply the first one
<fieldset>
<label for="departments">Department: </label>
<select id="departments" name="department" th:value="${user.department}">
<option th:value="accounting">Accounting</option>
<option th:value="sales">Sales</option>
<option th:value="'information technology'">IT</option>
<option th:value="'human resources'">HR</option>
</select>
</fieldset>
The salary is displayed fine, on the other hand
<fieldset>
<label for="salary">Salary: </label>
<input id="salary" name="salary" th:value="${user.salary}"/>
</fieldset>