Reputation: 621
I can return a list of cars to localhost:8080/list
but not in
localhost:8080/car
. My goal is to render the list just below the Car Form in car.html
.
I have tried two scenarios when rendering a list using Thymeleaf : With controller method getAllCars()
mapped to /list
I'm able to render the list on list.html
however with the same method mapped to /car
I get en error when trying to render to car.html
.
I'm sure there is something small that I'm missing here. Perhaps its my use of controller methods when trying to render the list on car.html
. The html
I successfully used on list.html
is the same I use when I add it to car.html
with the Car Form. I simply comment/uncomment the necessary code to attempt each scenario.
Working Scenario : Using getAllCars() method in CarController mapped to list.html
@Controller
public class CarController {
@Autowired
private CarService carService;
//PRESENT VIEW car.html
@GetMapping("/car")
public String carForm(Model model) {
model.addAttribute("car", new Car());
return "car";
}
//GET list of cars. render to /list
@RequestMapping("/list")
public String getAllCars(Model model) {
model.addAttribute("cars", carService.getAllCars());
return "list";
}
//GET list of cars. Render to /car
// @RequestMapping("/car")
// public String getAllCars(Model model) {
// model.addAttribute("cars", carService.getAllCars());
// return "car";
// }
//POST TO DATABASE
@PostMapping("/car")
public void carSubmit(@ModelAttribute Car car) {
carService.addCar(car);
}
}
list.html --> this works fine
This is the html code
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Car List</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Make</th>
<th>Model</th>
<th>Year</th>
</tr>
</thead>
<tbody>
<!-- if true, display this -->
<tr th:if="${!cars}">
<td colspan="2"> No Cars Available</td>
</tr>
<!-- otherwise, iterate over list and display info -->
<tr th:each="car : ${cars}">
<td><span th:text="${car.id}">Id</span></td>
<td><span th:text="${car.make}">Make</span></td>
<td><span th:text="${car.model}">Model</span></td>
<td><span th:text="${car.year}">Year</span></td>
</tbody>
</table>
</body>
</html>
Non-Working Scenario : Using getAllCars() method in CarController mapped to car.html
For brevity, see commented getAllCars() method in above CarController car.html --> this does not work
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Car Form</h1>
<form action="#" th:action="@{/car}" th:object="${car}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p>Make: <input type="text" th:field="*{make}" /></p>
<p>Model: <input type="text" th:field="*{model}" /></p>
<p>Year: <input type="text" th:field="*{year}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<h1>Car List</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Make</th>
<th>Model</th>
<th>Year</th>
</tr>
</thead>
<tbody>
<!-- if true, display this -->
<tr th:if="${!cars}">
<td colspan="2"> No Cars Available</td>
</tr>
<!-- otherwise, iterate over list and display info -->
<tr th:each="car : ${cars}">
<td><span th:text="${car.id}">Id</span></td>
<td><span th:text="${car.make}">Make</span></td>
<td><span th:text="${car.model}">Model</span></td>
<td><span th:text="${car.year}">Year</span></td>
</tbody>
</table>
</body>
</html>
And this is the error I am facing
2019-08-27 12:30:32.519 ERROR 22384 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "car": Exception evaluating SpringEL expression: "!cars" (template: "car" - line 33, col 9)
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "!cars" (template: "car" - line 33, col 9)
Upvotes: 0
Views: 175
Reputation: 3086
I think I got your problem. You are redirecting to car.html
page with controller
@GetMapping("/car")
public String carForm(Model model) {
model.addAttribute("car", new Car());
return "car";
}
In the same page you are both showing your car list and saving with form. But you hadn't put cars
with a model
in this controller. That's why you are getting a template error. To resolve this problem you need to put cars
in the previous controller. So modify your controller
@GetMapping("/car")
public String carForm(Model model) {
model.addAttribute("car", new Car());
return "car";
}
to
@GetMapping("/car")
public String carForm(Model model) {
model.addAttribute("car", new Car());
model.addAttribute("cars", carService.getAllCars());
return "car";
}
Now after posting car you have to redirects to a page. But you didn't do that. So modify your controller
@PostMapping("/car")
public void carSubmit(@ModelAttribute Car car) {
carService.addCar(car);
}
to
@PostMapping("/car")
public String carSubmit(@ModelAttribute Car car) {
carService.addCar(car);
return "redirect:/car"
}
Hope it will work. Give a shout!
Upvotes: 1
Reputation: 1
I think the issue is that, you are redirecting to car.html
with 2 different methods.
So only the first one, ie
@GetMapping("/car")
public String carForm(Model model) {
model.addAttribute("car", new Car());
return "car";
}
is working and not,
@RequestMapping("/car")
public String getAllCars(Model model) {
model.addAttribute("cars", carService.getAllCars());
return "car";
}
so either you can do like,
@GetMapping("/car") public String carForm(Model model) { model.addAttribute("car", new Car()); return getAllCars(model); }
or use any one method exactly, or even give different url mappings for both
Also please let me know why exactly you have commented out the
getallcars
method? Are you getting any ambiguous mapping error while uncommenting the method.
Upvotes: 0
Reputation: 5239
It's saying there's an issue with the expresion !cars
which can be found in your car
template:
<tr th:if="${!cars}">
<td colspan="2"> No Cars Available</td>
</tr>
However the attribute passed to the car template in carForm
is car
and not cars
.
Upvotes: 0