Why is there nothing in my userConsul model - spring-boot

When I submit the form I want to collect the userConsult information. I then call my repository and call the Insert method. inside the brackets I include e.g.
userRepo.insertoIntoDB(userConsult.getepidemiology);
(I have left the other get methods as it is so long.
I run this and when I check my database I notice that only the fields I didnt use userConsult have items inside.
I think there is something to do with my options/select tag however I am unsure why there is nothing inside it. It works fine when I use input tags. I am using thymeleaf.
The Insert function works fine if I give it test inputs myself.
Please see my code below:
<form method="POST" th:action="#{/saveConsultation}" th:object="${userConsul}">
<label for="epidemiology">EPIDEMIOLOGY:</label>
<select id="epidemiology">
<option th:each="data : ${consultationData}"
th:text="${data.epidemiology}"
th:value="${data.epidemiology}">
</select>
<a th:href="#{/saveConsultation/{id}(id = ${patient.patientNumber})}" type="submit">Submit</a>
<input type="reset" value="Reset diagnosis">
</form><br>
Consultation Controller:
#RequestMapping("/saveConsultation/{id}")
public String saveConsultation(#ModelAttribute("userConsul") userConsul userConsul,HttpSession session,Model model,#PathVariable("id") int patientID){
Object USER_SESSION = session.getAttribute("USER_SESSION");
if (USER_SESSION == null) {
session.setAttribute("message", "You need to login to access the Consultation page");
return "redirect:/login";
}
User OldUser = (User) USER_SESSION;
int userId = OldUser.getID();
userRepository.insertIntoUserCase(userConsul.getEpidemiology(),userConsul.getComplaints(),userConsul.getExamination(),userConsul.getDiagnosis1(),userConsul.getDiagnosis2(),userConsul.getDiagnosis3(),patientID,userId);
return "test";
}

Related

How to show appropriate message on page with Thymeleaf if list is empty

I have some controller that is connected with some lists, now that list can be empty, I'm trying to provide a user message on page if list is empty. To be more clear, user can have wallet, inside that wallet user can create a transactions, because all of that I have a page Transactions now, if user still didnt create any transaction but visit that page, I want to show him message like You didnt create any transaction.
I found this example, and tried to apply on my problem, but so far it didnt work: How to check null and empty condition using Thymeleaf in one single operation?
This is my controller:
#GetMapping("/userTransactions/{user_id}")
public String getUserTransactions(#PathVariable("user_id") long user_id, TransactionGroup transactionGroup, Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl user = (UserDetailsImpl) authentication.getPrincipal();
long userId = user.getId();
model.addAttribute("userId", userId);
List<Transaction> transactions = transactionRepository.getTransactionsByUserId(user_id);
List<TransactionGroup> transactionByDate = new ArrayList<>();
List<Transaction> transOnSingleDate = new ArrayList<>();
boolean currDates = transactions.stream().findFirst().isPresent();
if (currDates) {
LocalDate currDate = transactions.get(0).getDate();
TransactionGroup transGroup = new TransactionGroup();
for (Transaction t : transactions) {
if (!currDate.isEqual(t.getDate())) {
transGroup.setDate(currDate);
transGroup.setTransactions(transOnSingleDate);
transactionByDate.add(transGroup);
transGroup = new TransactionGroup();
transOnSingleDate = new ArrayList<>();
}
transOnSingleDate.add(t);
currDate = t.getDate();
}
transGroup.setDate(currDate);
transGroup.setTransactions(transOnSingleDate);
transactionByDate.add(transGroup);
} else {
System.out.println("Empty");
model.addAttribute("transactionGroup", "NoData");
}
model.addAttribute("transactionGroup", transactionByDate);
return "transactions";
}
And that seems to work fine, I mean, if I didn't create a transaction, message System.out.println("Empty"); will be printed, but message on page is not displayed neither.
This is thymeleaf:
<div class="date" th:each="singleGroup : ${transactionGroup}">
<h1 th:text="${singleGroup .date}"></h1>
<div class="transaction" th:each="singleTrans : ${singleGroup.transactions}">
<h2>Amount: <span th:text="${singleTrans.amount}"></span></h2><br>
<h2>Note: <span th:text="${singleTrans.note}"></span></h2><br>
<h2>Wallet name: <span th:text="${singleTrans .walletName}"></span></h2><br>
<h2>Expense Category: <span th:text="${singleTrans .expenseCategories}"></span></h2><br>
<h2>IncomeCategory: <span th:text="${singleTrans .incomeCategories}"></span></h2>
<a class="card__link" th:href="#{/api/transaction/delete/{id}(id=${singleTrans.id})}"
th:data-confirm-delete="|Are you sure you want to delete ${singleTrans.walletName} wallet?|"
onclick="if (!confirm(this.getAttribute('data-confirm-delete'))) return false">Delete</a>
<hr>
</div>
<th:block th:if="${transactionGroup=='NoData'}"> No Data Found </th:block>
</div>
And here is the part: <th:block th:if="${transactionGroup=='NoData'}"> No Data Found </th:block> But its not displayed if list is empty
What I'm missing?
You can check if your list is empty like this
<div th:if="${#lists.isEmpty(transactionGroup)}"> No Data Found </div>
<div th:if="${#lists.size(transactionGroup) ==0}"> No Data Found </div>
In addition to that, your th:block is placed inside the list outer loop and it should be outside. That's why you're not seeing anything when the list is empty.

Laravel Calling Multiple Controllers from Form Submit

I want to submit a form, and once that submit button is pressed, I run a bit of code.
During this 'bit of code', part of its job will be to create a student, and also create a lunch order. (information pulled from the form).
From what I've been reading, I should be aiming to use CRUD, which would mean I should have a Student Controller and a LunchOrderController.
I want to call the #store method in each controller.
If I was doing it the 'bad' way, the form would have [action="/students" method=POST]. And in that route, it would then call /lunchorder/ POST, and then return to a page (redirect('students')).
However, as above, I don't want to call a controller from a controller. Therefore, the initial [action="/students" method=POST] should be something else instead, and this new entity will then call the StudentController, then call the LunchOrderController, then redirect('students').
But, I don't know what this new entity is, or should be, or how to link to it.
It is just a new route to a new controller which is ok to call other controllers from?
Or is there some other place I should be sending the form data to (maybe models?), to them call the controller? Or am I way off base and need to take some steps back?
I'm fairly new to Laravel but am wanting to use best practice as much as possible. All my reading of other posts don't seem to explain it enough to get my head around how its meant to work.
Edit: Some code to give an idea of what I'm getting at.
Student_edit.blade.php
<form action="/student" method="POST">
{{ csrf_field() }}
<label>First Name</label><input name="firstname" value="">
<label>Last Name</label><input name="lastname" value="">
<label>Lunch Order</label>
<select name="lunch_value" id="">
<option value="1" >Meat Pie</option>
<option value="2" >Sandwich</option>
<option value="3" >Salad</option>
<option value="4" >Pizza</option>
</select>
<input type="submit" value="Submit" class="btn btn-primary btn-lg">
</form>
web.php
Route::resource('/students', 'StudentController');
Route::resource('/lunchorder', 'LunchOrderController');
Studentcontroller
public function store(Request $request)
{
Student::create(request(['firstname', 'lastname']));
LunchOrderController::store($request, $student_id); //<- This isn't the correct syntax
return redirect('/students');
}
LunchOrderController
public function store(Request $request, $student_id)
{
LunchOrder::create(array_merge(request(['lunch_value']), ['student_id' => $student_id]));
return null;
}
Personally I would create a 'Logic' Directory as: app/Logic. Some people prefer Repositories etc, but this is my preference.
For your specific requirement I'd create the following file:
app/Logic/StudentLogic.php
StudentLogic
<?php
namespace App\Logic\StudentLogic;
use App\Student;
use App\LunchOrder;
class StudentLogic
{
public function handleStudentLunch(Request $request): bool
{
$student = Student::create(request(['firstname', 'lastname']));
if(is_null($student)) {
return false;
}
LunchOrder::create(array_merge(request(['lunch_value']), ['student_id' => $student->id]));
return true;
}
}
StudentController
public function store(Request $request)
{
$logic = new StudentLogic();
$valid = $logic->handleStudentLunch($request);
if($valid) {
return redirect('/students');
}
abort(404, 'Student Not Found');
}
ASSUMPTIONS
Student is stored under App/Student & LunchOrder is stored under App\LunchOrder
You will also need to use App\Logic\StudentLogic in StudentController
The reason I'd split this out into a Logic file is because I do not like 'heavy' controllers. Also, I'm not entirely sure what you're trying to acomplish here, but creating a student on the same request you create a LunchOrder seems like you're asking for trouble

Form with a select (drop-down) doesn't show error code

I have a form that contains a select to list all teachers by id in the system but it is not working properly.
Here is the code part of the form
and the corresponding path controller requests
I'm Using Thymeleaf and Spring Boot, so 'pr' corresponds a name for a variable of a repository of teachers.
<form th:action="#{/professor/updateProfessor/}" method="post" th:object="${professor}">
<div class= "form-group">
<label th:for = "id">Id</label>
<select th:field="*{id}">
<option
th:value = "${id}"
th:text = "${professor.id}">
</option>
</select>
</div>
<input type = "submit" value = "Add Professor">Save</button>
</form>
#GetMapping(value = {"/selecionaProfessor"})
#ResponseBody
public ModelAndView professorSelecao(){
ModelAndView atualizaProfessor = new ModelAndView("/atualizaProfessor");
atualizaProfessor.addObject("Add Professor");
return atualizaProfessor;
}
#PostMapping(value = {"/selecionaProfessor"})
#ResponseBody
public ModelAndView selecaoProfessor(){
ModelAndView pagSucesso = new ModelAndView("/pagSucesso");
pagSucesso.addObject(pr.findAll());
return pagSucesso;
}
From your controller, send a list of professors as per following to your view. Here you are associating the list of professors to the "professorList" :
model.addAttribute("professorList", pr.findAll());
And then to access above "professorList" in your thymeleaf do (similar to) this :
<option th:each="professor: ${professorList}" th:value="${professor}"> </option>
Not a full code but i hope you got the idea to get started.
For a full example, take a look here and here.
First of all what is not working? because I see a lot of things that may not work maybe because I don't see the all code or I am guessing some things, let's see
When you enter to your controller using
localhost:8080/professor/selecionaProfessor
are you expecting to use the form you put right? (the next code)
<form th:action="#{/professor/updateProfessor/}" method="post" th:object="${professor}">
<div class= "form-group">
<label th:for = "id">Id</label>
<select th:field="*{id}">
<option
th:value = "${id}"
th:text = "${professor.id}">
</option>
</select>
</div>
<input type = "submit" value = "Add Professor">Save</button>
</form>
because if that's correct you have a problem in your method:
#GetMapping(value = {"/selecionaProfessor"})
#ResponseBody
public ModelAndView professorSelecao(){
ModelAndView atualizaProfessor = new ModelAndView("/atualizaProfessor");
atualizaProfessor.addObject("Add Professor");
return atualizaProfessor;
}
you will get an error saying:
Neither BindingResult nor plain target object for bean name 'professor' available as request attribute
So you're missing to add the Key professor and a List so change:
atualizaProfessor.addObject("Add Professor");
with something like:
atualizaProfessor.addObject("professor", someListOfProfessorHereFromTheService (List<Professor>));
and it should work if your profesor object have the attributes you have on your form.
Now let's suppose that that worked before and the error wasn't that.
When you enter to your form if you see here:
form th:action="#{/professor/updateProfessor/}"
you're using updateProfessor I don't see that on your controller you have
#PostMapping(value = {"/selecionaProfessor"})
So I think that you should change the url mapping inside the html page or the controller and use the same as error 1, map the object using a key and value and iterate the list into the html as I showed in the 1st error
Hope it helps

If search don't return values from database show an empty form

So i got a page that have a search form, and when the user search for a value if there are no records on database the form returns empty, but if there are records the form is populated with data.
What i was thinking was this
var db = Database.Open("myDataBase");
var selectCommand = "SELECT * FROM exportClient";
var searchTerm = "";
if(!Request.QueryString["searchField"].IsEmpty() ) {
selectCommand = "SELECT * FROM exportClient WHERE clientAccount = #0";
searchTerm = Request.QueryString["searchField"];
}
if(IsPost){
var selectedData = db.Query(selectCommand, searchTerm);
}
And Then:
<body>
<div class="col_12">
<form method="get">
<label>search</label><input type="text" class="col_3" name="searchField" />
<button type="submit" class="button red" value="search">search</button>
</form>
</div>
#if(!Request.QueryString["searchField"].IsEmpty() ){
foreach(var row in db.Query(selectCommand, searchTerm)) {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM POPULATED
</form>
</div>
}
} else {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM NOT POPULATED
</form>
</div>
}
</body>
But what is happening is that the form that is not populated is always showing up when i enter the page, and i need that the only thing that user see when enter the page is the input field to do the search.
What am i doing wrong ?
I'm not sure of having understood your goal, but in my opinion your main problem is to detect if either exists or not a query string.
I think that your code should be like this
#if(Request.QueryString.HasKeys())
{
if(!Request.QueryString["searchField"].IsEmpty() ){
<p>searchField has value</p>
} else {
<p>searchField hasn't value</p>
}
}
There are a number of potential issues I can see with your code, hopefully you can put these together to achieve what you wanted:
As Selva points out, you are missing the action attribute on your forms.
The selectedData variable you create inside your IsPost() block goes out of scope before you do anything with it. Perhaps you didn't include all your code though, so ignore this if it just isn't relevant to the question.
To answer the main question: if you don't want the empty form to appear when the user hasn't yet performed a search, surely you just need to completely remove the else block - including the empty form - from your HTML?
Hope that helps.

how to do binding in Spring annotated request parameter?

i have a controller that is using annotation for request mapping and requestParam.
the controller is working fine. However when submitting a command object with array, spring will crap out saying array index out of bound. i am guessing there is something wrong with binding but don't know how to fix it.
to be more specific, in eclipse i would set debugger at the beginning of the controller, and when submitting the form (by hitting a input submit button) eclipse debugger will not trigger and i will see array index out of bound error in console.
the controller is something like this:
#RequestMapping(value = {"/internal/pcsearch.dex", "/external/pcsearch.dex"},
method = {RequestMethod.POST, RequestMethod.GET})
public ModelAndView executeProductCatalogSearch(
HttpServletRequest request,
#RequestParam(value = "cat" ,required = false) String cat,
#RequestParam(value = "brand" ,required = false) String brand,
#ModelAttribute("command") ProductCatalogCommand cmd
){
[edit]
and the jsp is like:
<form name="pForm"
id="pForm"
action="<c:url value="psearch.dex"><c:param name="cat" value="${cat}"/></c:url>"
method="POST"
style="display:inline;">
...
...
<c:forEach var="model" items="${models}" varStatus="modelLinkStatus">
<script>
var modelImg<c:out value="${modelLinkStatus.index}"/>Src = '<c:out value="${model.altModelImage}"/>';
</script>
<spring:bind path="command.models[${modelLinkStatus.index}].modelSkusDisplayed">
<input type="hidden" name="<c:out value="${status.expression}"/>" id="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>"/>
</spring:bind>
<spring:bind path="command.updateCartButton">
<input type="submit" value="<spring:message code="orderEntryMessages.ecatalog.button.addToCart" text="Add to Cart" htmlEscape="yes" />" name="<c:out value="${status.expression}"/>" id="<c:out value="${status.expression}"/>" class="sub_buttons"/>
</spring:bind>
...
and the command object declare the model array as:
private List<ModelLink> models = new ArrayList<ModelLink>();
where modelLink is a custom ds.
the first foreach tag handle the the model command object and the 2nd part is the submit button i clicked on.
i think you should use AutoPopulatingList as models to bind list to view and controller. for example please refer link. This might resolve your problem of index.

Resources