Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialRonald Williams
Java Web Development Techdegree Graduate 25,021 PointsWhy am I getting a 400 error? Java, Thymeleaf, Spring boot
BACKGROUND:
I am making a spring-boot web app with Thymeleaf. It is a Recipe site and I am working on the part where a user can add a Recipe. I am trying to make it so that a user can add an ingredient to a Recipe's ingredient list.
In the controllers I give the user a recipe form with a recipe object and one ingredient. If the user clicks a button to add an ingredient the form submits to /recipes/ingredient. Then in that controller I am trying to add one ingredient and redirect the user to the form.
Any help greatly appreciated!
PROBLEM:
When I click the add ingredient button I get a 400 error.
Code for the two controllers: (Note: once I get this part to work I am going to use a third controller for saving the recipe.)
@RequestMapping(value = "/recipes/add")
public String addRecipeForm(Model model, Principal principal) {
checkForUser(model, (UsernamePasswordAuthenticationToken) principal);
if (!model.containsAttribute("recipe")) {
Recipe recipe = new Recipe();
recipe.getIngredients().add(new Ingredient("", "", 0));
model.addAttribute("recipe", recipe);
}
model.addAttribute("category", Category.values());
model.addAttribute("action", String.format("/recipes/add"));
model.addAttribute("heading", "Recipe Creator");
return "form";
}
@RequestMapping(value = "/recipes/ingredient", method = RequestMethod.POST)
public String addIngredient(Recipe recipe, RedirectAttributes redirectAttributes) {
recipe.getIngredients().add(new Ingredient("", "", 0));
redirectAttributes.addFlashAttribute("recipe", recipe);
return "redirect:/recipes/add";
}
// Third Controller used later to save Recipe
@RequestMapping(value = "/recipes/add", method = RequestMethod.POST)
public String addRecipe(Recipe recipe, ModelMap modelMap) {
recipeService.save(recipe);
return String.format("redirect:/recipes/details/%s", recipe.getId().toString());
}
Code for the Form.html template:
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head th:replace="layout :: common_header(~{::title})">
<title>Recipe Editor | My Recipes</title>
</head>
<body>
<nav th:replace="layout :: nav"></nav>
<div class="grid-container">
<div th:replace="layout :: logo"></div>
<div class="grid-100">
<div class="recipes">
<form id="recipe-form" th:action="@{/recipes/ingredient}" method="post" th:object="${recipe}">
<div class="grid-100 row controls">
<div class="grid-50">
<h2 th:text="${heading}"> Recipe Heading </h2>
</div>
<input type="hidden" th:field="*{id}" />
<div class="grid-50">
<div class="flush-right">
<button type="submit" name="save">Save Recipe</button>
<button class="secondary">Cancel</button>
</div>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Photo </label>
</p>
</div>
<div class="grid-40">
<p>
<input placeholder="Url"/>
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Name </label>
</p>
</div>
<div class="grid-40">
<p>
<input type="text" th:field="*{name}"/>
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Description </label>
</p>
</div>
<div class="grid-40">
<p>
<input type="textarea" th:field=="*{description}" />
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Category </label>
</p>
</div>
<div class="grid-30">
<p>
<select th:field="*{category}">
<option value="">All Categories</option>
<div th:each="category : ${categories}">
<option th:value="${category}" th:text="${category}">Category</option>
</div>
</select>
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Prep Time </label>
</p>
</div>
<div class="grid-20">
<p>
<input type="text" th:field="*{prepTime}"/>
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Cook Time </label>
</p>
</div>
<div class="grid-20">
<p>
<input type="text" th:field=="*{cookTime}"/>
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Ingredients </label>
</p>
</div>
<div class="grid-30"><p class="label-spacing">Item</p></div>
<div class="grid-30"><p class="label-spacing">Condition</p></div>
<div class="grid-20"><p class="label-spacing">Quantity</p></div>
<div th:each="ingredient : *{ingredients}">
<div class="grid-20"><p class="label-spacing"></p></div>
<div class="grid-30">
<p class="label-spacing">
<input type="text" th:value="${ingredient.item}"/>
</p>
</div>
<div class="grid-30">
<p class="label-spacing">
<input type="text" th:value="${ingredient.condition}"/>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<input type="text" th:value="${ingredient.quantity}"/>
</p>
</div>
</div><!-- each ingredient -->
<div class="prefix-20 grid-80 add-row">
<p>
<button type="submit">+ Add Another Ingredient</button>
</p>
</div>
</div> <div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Steps </label>
</p>
</div>
<div class="step-row">
<div class="prefix-20 grid-80">
<p>
<input/>
</p>
</div>
</div>
<div class="prefix-20 grid-80 add-row">
<p>
<button>+ Add Another Step</button>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row controls">
<div class="grid-50"><h2></h2></div>
<div class="grid-50">
<div class="flush-right">
<button type="submit">Save Recipe</button>
<button class="secondary">Cancel</button>
</div>
</div>
</div>
<div class="clear"></div>
<div class="row"> </div>
</form>
</div> <!-- recipes -->
</div> <!-- grid-100 -->
</div> <!-- grid-container -->
<div th:replace="layout :: scripts"></div>
</body>
</html>
1 Answer
Katsiaryna Krauchanka
Full Stack JavaScript Techdegree Graduate 22,154 PointsHey Ronald Williams, did you find a solution? I experience similar issue