I'm having an issue where I have a form that will save all updates to a formula. This loads fine and everything works except for when trying to delete an ingredient within a list that is in the updateFormula object.
When I pass my two @RequestParameters in to delete a specific ingredient, I recieve the error:
Required request parameter 'formulaId' for method parameter type String is not present
This has stumped me as the formulaId parameter is for the first @GetMapping method updateFormula, which retrieves the formula information that can be updated. I have tried adding the formulaId as a model object, and pass that into the deleteIngredientInFormula method, but that did not work either.
@GetMapping to get all formula details to display
@GetMapping("/update-formula")
public String updateFormula(@RequestParam("formulaId") String id, Model model) {
//unwraps the optional formula object if present, then adds to the model.
formulaService.getFormulaById(id).ifPresent(f -> model.addAttribute("updatedFormula",f));
return "Update-Formula-Form";
}
@GetMapping to select a specific ingredient in the list to delete
@GetMapping("delete-ingredient")
public String deleteIngredientInFormula(@RequestParam("ingredientId") String inId,
@RequestParam("formId") String formId) {
formulaService.deleteIngredientInFormula(formId, inId);
return "redirect:/update-formula";
}
Thymeleaf Page: Update-Formula-Form
<div class="container">
<h2>Formula Update Form</h2>
<form action="#" th:action="@{/save-updated-formula}" method="post" th:object="${updatedFormula}">
<input type="text" th:readonly="true" th:field="*{formulaId}">
<input type="text" th:field="*{formulaName}">
<input type="text" th:field="*{dosageForm}">
<input type="text" th:readonly="true" th:field="*{unitWeight}">
<input type="text" th:field="*{servingSize}">
<!--FORMULA INGREDIENTS (SELECT ACTION) -->
<div class="container table-responsive">
<table class="table table-striped">
<thead class="table-light">
<tr>
<td>Ingredient ID</td>
<td>Ingredient Name</td>
<td>Type</td>
<td>Potency</td>
<td>Manufacturer</td>
<td>Label Claim (mg)</td>
<td>Delete Ingredient</td>
</tr>
</thead>
<tbody>
<tr th:each="ingredient, holder : *{ingredients}">
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].ingredientId}"></td>
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].ingredientName}"></td>
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].type}"></td>
<td><input th:field="*{ingredients[__${holder.index}__].potency}"></td>
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].manufacturer}"></td>
<td><input th:field="*{ingredients[__${holder.index}__].labelClaim}"></td>
<td>
<a th:href="@{/delete-ingredient(ingredientId=${ingredient.getIngredientId()}, formId=${updatedFormula.getFormulaId()})}"
class="btn btn-info btn-sm">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
<button type="submit" class="btn btn-info col-2">Save Formula Details</button>
</form>
</div>
CodePudding user response:
When you call the @GetMapping("delete-ingredient")
endpoint you are then redirecting to update-formula
which requires formulaId
. That is why you are getting the error. You are basically redirecting to update-formula
without any additional data. You need to add that as follows:
@GetMapping("delete-ingredient")
public String deleteIngredientInFormula(@RequestParam("ingredientId") String inId,
@RequestParam("formId") String formId) {
formulaService.deleteIngredientInFormula(formId, inId);
return "redirect:/update-formula?formulaId=" formId;
}
Additionally, you might want to use the same parameter names for the same thing. You have @RequestParam("formulaId") String id
and @RequestParam("formId") String formId
which if I understood this correctly are one and the same thing formulaId
.
Finally, you definitely shouldn't use a GET to delete data. That is why the DELETE HTTP method exists.