Home > database >  User cant have a second chance for input if first time enter wrong data
User cant have a second chance for input if first time enter wrong data

Time:01-10

So actually I have an controller that show form to user. User get that form and for example if he enter a wrong data, for example amount field is just positive numbers but user insert -1 user will get error message on screen, but when user change that value and enter for example 3 for amount and submit form, user get 404 Whitelabel Error Page.

So first URL is:

http://localhost:8080/api/transaction/expenseTransaction/4, now, user enter -1 for amount and click submit, URL is http://localhost:8080/api/transaction/saveExpense/4, so is there any way to stay on same page and allow user to save form after he insert properly data?

I have this controller to show form:

@GetMapping("/expenseTransaction/{id}")
public String expenseTransaction(@PathVariable(value = "id") long id, Transaction transaction, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();
    model.addAttribute("userId", userId);


    model.addAttribute("transaction", transaction);
    model.addAttribute("expenseCategories", ExpenseCategories.values());

    return "expense_transaction";

}

This is the form:

<div >
<h3> Expense transaction</h3>
<div >
    <div >
        <div >
            <form action="#"
                  th:action="@{/api/transaction/saveExpense/{walletId} (walletId=${id})}"
                  th:object="${transaction}" method="post">
                <div >
                    <div >
                        <label for="amount" >Amount</label> <input
                            type="text" th:field="*{amount}"  id="amount"
                            placeholder="amount"> <span
                            th:if="${#fields.hasErrors('amount')}" th:errors="*{amount}"
                            ></span>
                    </div>
                    <div >
                        <label for="note" >Note</label> <input
                            type="text" th:field="*{note}"  id="note"
                            placeholder="note"> <span
                            th:if="${#fields.hasErrors('note')}" th:errors="*{note}"
                            ></span>
                    </div>
                    <div >
                        <label for="date" >Date</label> <input
                            type="date" th:field="*{date}" 
                            id="date" placeholder="date"> <span
                            th:if="${#fields.hasErrors('date')}" th:errors="date"
                            ></span>
                    </div>
                    <div >
                        <label for="date" >Category</label>
                        <select th:field="${transaction.expenseCategories}">
                            <option value="0">Select expense category</option>
                            <option
                                    th:each="expenseCategories : ${expenseCategories}"
                                    th:value="${expenseCategories}"
                                    th:text="${expenseCategories.displayName}"
                            ></option>
                        </select>
                    </div>

                    <div >
                        <input type="submit" 
                               value="Update Student">
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

This is controller to save that form:

@PostMapping("/saveExpense/{walletId}")
public String saveExpense(@PathVariable(value = "walletId") long walletId,
                          @Valid Transaction transaction, BindingResult result, Model model) {

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
    long userId = user.getId();

    Wallet wallet = walletService.getWalletById(walletId);

    boolean thereAreErrors = result.hasErrors();
    if (thereAreErrors) {
        transaction.setId(walletId);
        model.addAttribute("expenseCategories", ExpenseCategories.values());
        return "expense_transaction";
    }

    transaction.setWallet(wallet);
    transactionService.saveExpense(transaction, walletId, userId);
    return "redirect:/api/wallet/userWallet/balance/"   userId;

}

CodePudding user response:

The problem is your code.

Your get method is defined with @GetMapping("/expenseTransaction/{id}") and your POST method is defined with @PostMapping("/saveExpense/{walletId}").

The GET method will expose a variable named id in your model and fill that with the value of the path variable.

Your POST method will expose a variable named walletId in your model and fill that with the value of the path variable.

In your th:action you expect the id to be filled. Which is true for the GET not for the POST because the names are different.

Either fix your path variable names, or explicitly add id to the model in the POST method with the value from walletId.

  • Related