Spring controller null object ID - spring

When the user goes to recipe/new it sends a RecipeCommand object, then after the user sets the information and Recipe Ingredients and Directions, RecipeCommand objects gets send to recipe/new/ingredients. I convert it to a recipe object then save it and return it. Then I send an Ingredients Wrapper which has N RecipeCommands (depends the number the user set at Recipe Ingredients) and the RecipeCommand again and return to recipe/recipe_add_ingredients. This leads to recipe/new/{recipeId}/ingredients/directions. Then I take the IngredientsWrapper and add every IngredientCommand object to the RecipeCommand. The problem is that the object has a null ID even though I've added it into the database and it shows that it has the ID of 2. Here is the code:
add_recipe
<form th:object="${recipe}" th:action="#{/recipe/new/ingredients}" enctype="multipart/form-data">
<input type="hidden" th:field="*{id}">
<div class="add-recipe-container">
<div class="add-recipe-inputs-container">
<div class="add-recipe-inputs">
<ul class="add-recipe-inputs-list">
<li>
<label for="recipeName">Recipe Name </label>
<input id="recipeName" name="recipeName" th:field="*{recipeName}" type="text">
</li>
<li>
<label for="cookTime">Cook Time</label>
<input th:field="*{recipeCookTime}" placeholder="Without minutes" type="number">
</li>
<li>
<label for="prepTime">Prep Time</label>
<input th:field="*{recipePrepTime}" placeholder="Without minutes" type="number">
</li>
<li>
<label for="servings">Servings</label>
<input th:field="*{recipeServings}" type="number">
</li>
</ul>
</div>
</div>
<div class="add-recipe-options-container">
<div class="add-recipe-options">
<ul class="add-recipe-options-list">
<li>
<label>Difficulty</label>
<select th:field="*{difficulty}" id="difficulty.id">
<option th:each="difficultyEach : ${T(com.vio.spring5.domain.Difficulty).values()}"
th:value="${difficultyEach.id}"
th:text="${difficultyEach.name}">
</option>
</select>
</li>
<li>
<label>Category</label>
<select th:field="*{recipeCategory}" id="recipeCategory.id">
<option th:each="category : ${T(com.vio.spring5.domain.RecipeCategory).values()}"
th:value="${category.id}"
th:text="${category.name}">
</option>
</select>
</li>
<li>
<label for="ingredientsAmount">Ingredients</label>
<input th:field="*{recipeIngredientsAmount}" type="number">
</li>
<li>
<label for="directionsAmount">Directions</label>
<input th:field="*{recipeDirectionsAmount}" type="number">
</li>
<li>
<label for="">Image</label>
<input th:field="*{image}" id="imagefile" name="imagefile" type="file" class="file">
</li>
</ul>
</div>
</div>
</div>
<button type="submit" class="next-page-button">Next</button>
</form>
add_ingredient
<form th:object="${ingredientsWrapper}" th:action="#{'/recipe/new/' + ${recipe.getId()} + '/ingredients/directions'}" method="get">
<div class="add-recipe-container">
<ul class="recipe-many">
<li th:each="ingredientInputs, iter : ${ingredientsWrapper.ingredientsWrapperSet}">
<ul class="add-recipe-ingredients-list">
<li>
<label for="">Amount</label>
<input th:field="*{ingredientsWrapper[__${iter.index}__].amount}" type="number">
</li>
<li>
<label for="">Unit</label>
<select th:field="*{ingredientsWrapper[__${iter.index}__].unitOfMeasure}">
<option th:each="unit : ${unitOfMeasure}"
th:value="${unit.id}"
th:text="${unit.unitName}">Test</option>
</select>
</li>
<li>
<label for="">Ingredient Name</label>
<input th:field="*{ingredientsWrapper[__${iter.index}__].ingredientName}" type="text">
</li>
</ul>
</li>
</ul>
</div>
<button type="submit" class="add-recipe">Add Recipe</button>
</form>
add_directions
<form th:object="${directionsWrapper}" th:action="#{'/recipe/new/' + ${recipe.id} + '/ingredients/directions'}" method="post">
<div class="add-directions-container">
<ul class="directions-many">
<li th:each="directions, iter : ${directionsWrapper.directionsWrapperList}">
<label>Step: </label>
<textarea th:field="*{directionsWrapper[__${iter.index}__].directions}" cols="40" rows="3"></textarea>
</li>
</ul>
</div>
<button type="submit" class="add-recipe">Add Recipe</button>
</form>
Controllers
/*
* Send a RecipeCommand object to front
*/
#GetMapping(value = "/recipe/new")
public String newRecipe(Model model) {
model.addAttribute("recipe", new RecipeCommand());
return "recipe/recipe_add";
}
/*
* Send the recipe wrapper
* To do: throw exception and validation
*
*/
#GetMapping(value = "/recipe/new/ingredients")
public String addIngredients(#ModelAttribute("recipe") RecipeCommand recipe, BindingResult bidingResult, Model model) {
recipeService.saveRecipeCommand(recipe);
IngredientsWrapper wrapper = new IngredientsWrapper();
addIngredientsCommandObjects(wrapper, recipe.getRecipeIngredientsAmount());
model.addAttribute("unitOfMeasureSet", uomService.findAll());
model.addAttribute("ingredientsWrapper", wrapper);
model.addAttribute("recipe", recipe);
return "recipe/recipe_add_ingredients";
}
/*
* to do: validate
*/
#GetMapping(value = "/recipe/new/{recipeId}/ingredients/directions")
public String addDirections (#PathVariable String recipeId,
#ModelAttribute("ingredientsWrapper") IngredientsWrapper wrapper, Model model) {
RecipeCommand recipe = recipeService.findRecipeCommandById(Long.valueOf(recipeId));
wrapper.ingredientsWrapperSet
.iterator()
.forEachRemaining(ingredient -> recipe.addIngredient(ingredient));
recipeService.updateRecipeCommandIngredients(recipe);
DirectionsWrapper directionsWrapper = new DirectionsWrapper();
addDirectionsCommandObjects(directionsWrapper, recipe.getRecipeDirectionsAmount());
model.addAttribute("directionsWrapper", directionsWrapper);
model.addAttribute("recipe", recipe);
return "recipe/recipe_add_directions";
}
/*
* to do: validate
*/
#PostMapping(value = "/recipe/new/{recipeId}/ingredients/directions/")
public String addRecipe(#PathVariable String recipeId,
#ModelAttribute("directionsWrapper") DirectionsWrapper wrapper) {
RecipeCommand recipe = recipeService.findRecipeCommandById(Long.valueOf(recipeId));
wrapper.directionsWrapperList
.iterator()
.forEachRemaining(directions -> recipe.addDirections(directions));
recipeService.updateRecipeCommandDirections(recipe);
return "redirect:/browse";
}

Related

pass object from HTML template back to the controller

I have the following HTML block. I want to pass the object "jobDTO" back to the contoller "/deleteJob" method. Whatever I do I am getting null object.
<th:block th:if="${jobDTO != null}" th:each="jobDTO: ${allJobDTOs.get(jobGroup)}">
<div id="accordion2" style="margin-bottom: 3px;">
<div class="card" id="headingOne">
<div class="card-header" style="padding: 0">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" th:attr="data-target='#accordion2_'+${jobDTO.identity.name}"
aria-expanded="true" aria-controls="collapseChild" >
<p class="font-weight-bold custom-p identity-black" > Job Identity </p>
<p class="custom-p" style="padding-left: 52px;" th:text="${jobDTO.identity.group} +' , ' + ${jobDTO.identity.name}"></p>
</button>
</h5>
</div>
<div th:id="'accordion2_'+${jobDTO.identity.name}" class="collapse" aria-labelledby="headingOne" data-parent="#accordion2">
<div class="card-body">
<dl class="row">
<dt class="col-lg-3">Trigger List</dt>
<dd class="col-sm-9">
<th:block th:each="trigger: ${jobDTO.triggers}">
<p><b>nextFireTime</b> <span th:text="${trigger.nextFireTime}"> </span></p>
<hr>
</th:block>
</dd>
</dl>
<!-- important part.. how to pass the jobDTO object back to the controller -->
<form id="form2" action="#" th:action="#{/deleteJob}" th:object="${jobDTO}" th:method="post">
<input type="text" th:value="*{identity.name}" th:field="*{identity.name}" hidden/>
<button type="submit" value="Submit" class="btn btn-danger btn-sm" >Delete Job</button>
</form>
</div>
</div>
</div>
</div>
</th:block>
my controller relevant parts are:
#GetMapping(value = "/deleteJob")
public String deleteJobPage(Model model) {
model.addAttribute("jobDTO", new ScheduleJobDTO());
//Returns the Home page with the prepared model attributes
return "Home";
}
// =================
#PostMapping("/deleteJob")
public String deleteJob(#ModelAttribute final ScheduleJobDTO jobDTOReturn, BindingResult bindingResult, Model model) {
// I want to receive the jobDTO object here
schedulerService.deleteJobFromGroup(jobDTOReturn.getIdentity().getGroup(),
jobDTOReturn.getIdentity().getName());
return "redirect:/";
}
what I am missing here?
I think there is an error in your input tag, try this :
<input type="text" th:value="${jobDTO.identity.name}" th:field="*{identity.name}" hidden/>

How to fix query in edit view?

i'm setting up a new project to perform multi language form but i'm stuck in edit form i don't know how to handle that
I created my controller and create view the only thing i need is edit view
so you can check my create view in bellow that work fine :
<div class="card-body text-center">
{!! Form::open(['route' => 'content.store', 'method' => 'Post']) !!}
<div class="card">
<div class="card-body">
<div class="form-group">
<label class="mx-4" for="my-input">{{ __('content/form.country_t') }}:</label>
<input id="my-input " type="text" name="country" placeholder="{{ __('content/form.country') }}">
<label class="mx-4" for="my-input">{{ __('content/form.city_t') }}:</label>
<input id="my-input" type="text" name="city" placeholder="{{ __('content/form.city') }}">
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="card col-xs-12 p-0">
<nav>
<div class="nav nav-pills nav-fill card-header" id="nav-tab" role="tablist">
#foreach (config('translatable.locales') as $la=>$desc)
<a class="nav-item nav-link" id="nav-home-tab" data-toggle="tab" href="#{{ $la }}" role="tab" aria-controls="nav-home" aria-selected="true">{{ $desc }}</a> #endforeach
</div>
<div class="tab-content py-3 px-3 px-sm-0 card-body" id="nav-tabContent">
#foreach (config('translatable.locales') as $la=>$desc)
<div class="tab-pane fade px-4" id="{{ $la }}" role="tabpanel" aria-labelledby="nav-home-tab">
<div class="form-group">
<label for="my-input" class="">{{ __('content/form.title') }}</label>
<input id="my-input" class="form-control" type="text" name="translations[{{ $la }}][title]">
</div>
<div class="form-group">
<label for="my-input" class="">{{ __('content/form.body') }}</label>
<input id="my-input" class="form-control" type="text" name="translations[{{ $la }}][body]">
</div>
</div>
#endforeach
</div>
</nav>
</div>
<button type="submit" class="row col-12 mt-2 mx-auto btn btn-primary">{{ __('content/form.submit') }}</button>
</div>
</div>
</div>
</div>
{!! Form::close() !!}
</div>
and this is my controller :
public function store(Request $request)
{
$contents = new Content;
// $contents->fill($request->all());
$this->fillRequest($request,$contents);
$contents->User()->associate(\Auth::user());
$contents->saveOrFail();
return redirect()->route('content.index')->with('success','با موفقیت ساخته شد');
}
private function fillRequest(Request $request, Content $model)
{
//fill model on fillable variables
$model->fill($request->only($model->getFillable()));
$model->saveOrFail();
foreach ($request->translations as $la => $desc) {
//if title field is null ignore the translations
// in case of there is a translation... delete it
if (!$desc["title"]) {
if ($model->hasTranslation($la)) {
$model->deleteTranslations($la);
}
continue;
}
//create new translation if not exists
$model->translateOrNew($la)->fill($desc);
$model->saveOrFail();
}
return $model;
}
I need to know how can i create edit view exactly same as my create view above

pagination in spring boot whit a form parameter

I'm using spring boot and thymeleaf.
I have a page with a form that search by a specific param then submits the data as POST request.
The page shows the result in a table and works fine. The table shows the correct pagination options and result,
Problem: When I click the button to show results on page 2 o laters, then the POST data from the previous search is lost.
Question: How can I retain the POSTed data during pagination?
CONTROLLER:
#RequestMapping(value = "/list",method = {RequestMethod.POST, RequestMethod.GET})
public String list(#RequestParam(name = "page", defaultValue = "0") int page,
#RequestParam(name = "name", defaultValue = "") String name,
#RequestParam(name = "lastname", defaultValue = "") String lastname,
Pageable pageable,
Model model) {
Pageable pageRequest = new PageRequest(page, 4);
Cliente cliente = new Cliente();
Page<Cliente> clientes;
if (name.equals("") && lastname.equals("")) {
clientes = clienteService.findAll(pageRequest);
}else {
clientes = clienteService.findMatch(name, lastname, pageRequest);
}
PageRender<Cliente> pageRender = new PageRender<Cliente>("/listar", clientes);
model.addAttribute("titulo", "Listado de clientes");
model.addAttribute("clientes", clientes);
model.addAttribute("cliente", cliente);
model.addAttribute("page", pageRender);
return "listar";
}
HTML:
<form th:action="#{/listar}" th:object="${cliente}" method="post">
<div class="form-group row">
<label for="nombre" class="col-sm-2 col-form-label">Nombre</label>
<div class="col-sm-6">
<input type="text" th:field="*{nombre}" class="form-control"
th:errorclass="'form-control alert-danger'" /> <small
class="form-text text-danger"
th:if="${#fields.hasErrors('nombre')}" th:errors="*{nombre}"></small>
</div>
</div>
<div class="form-group row">
<label for="nombre" class="col-sm-2 col-form-label">Apellido</label>
<div class="col-sm-6">
<input type="text" th:field="*{apellido}" class="form-control"
th:errorclass="'form-control alert-danger'" /> <small
class="form-text text-danger"
th:if="${#fields.hasErrors('apellido')}" th:errors="*{apellido}"></small>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
<input type="submit" th:value="'Buscar'"
class="btn btn-secondary" />
</div>
</div>
</form>
Pagination:
<nav th:fragment="paginator">
<ul class="pagination">
<li class="page-item"
th:class="${page.first? 'page-item disabled': 'page-item'}"><span
class="page-link" th:if="${page.first}">Primera</span> <a
class="page-link" th:if="${not page.first}"
th:href="#{${page.url}(page=0)}">Primera</a></li>
<li class="page-item"
th:class="${not page.hasPrevious? 'page-item disabled': 'page-item'}">
<span class="page-link" th:if="${not page.hasPrevious}">«</span>
<a class="page-link" th:if="${page.hasPrevious}"
th:href="#{${page.url}(page=${page.paginaActual-2})}">«</a>
</li>
<li class="page-item" th:each="item : ${page.paginas}"
th:class="${item.actual? 'page-item active': 'page-item'}"><span
class="page-link" th:if="${item.actual}" th:text="${item.numero}"></span>
<a class="page-link" th:if="${not item.actual}"
th:href="#{${page.url}(page=${item.numero-1})}"
th:text="${item.numero}"></a></li>
<li class="page-item"
th:class="${not page.hasNext? 'page-item disabled': 'page-item'}">
<span class="page-link" th:if="${not page.hasNext}">»</span> <a
class="page-link" th:if="${page.hasNext}"
th:href="#{${page.url}(page=${page.paginaActual})}">»</a>
</li>
<li class="page-item"
th:class="${page.last? 'page-item disabled': 'page-item'}"><span
class="page-link" th:if="${page.last}">Última</span> <a
class="page-link" th:if="${not page.last}"
th:href="#{${page.url}(page=${page.totalPaginas-1})}">Última</a>
</li>
</ul>
</nav>
I had a similar situation where I used the request parameter. So the trick is to capture the request parameter based on what we perform the search. Then afterwards you can get that parameter (from URL) and use it in the links you are building for pagination.
For example, say, your post/get URL looks like this:
http://localhost:8080/listByName?name=earth
Then get the vale of "name" parameter and use it while building your pagination url (links) in your html table/list like this:
th:href="#{/listByName/(name=${#request.getParameter('name')},pageSize=${selectedPageSize}, page=${page})}"
for me it working perfectly. This way you wont have to go for additional code using flashAttributes or mucking with JavaScript.

How tell the view an error has occured from controller? (Spring MVC)

How can I say trigger error/validation messages in the view from the controller in a better way? Currently, I do this by sending boolean attributes. For example, in creating a product, I have two possible errors. Invalid format of UPC of a product, or duplicate upc. I also have a validati
#RequestMapping("/createProduct")
public String createProduct(Model model, #RequestParam(value = "name") String name,
#RequestParam(value = "upc") String upc, #RequestParam(value = "category") String categoryName,
#RequestParam(value = "description") String description, #RequestParam(value = "price") BigDecimal price,
#RequestParam(value = "stock") int stock){
model.addAttribute("activeTab", 3);
if(Validator.invalidUpcFormat(upc)){
model.addAttribute("invalidFormat", true); //trigger for invalid format
return "management";
}
Category category = productService.getCategory(categoryName);
Product product = new Product(upc, category, name, description, price);
InventoryProduct inventoryProduct = new InventoryProduct(product, stock);
try {
managerService.add(inventoryProduct);
model.addAttribute("productCreated", true);
} catch (DuplicateProductException e) {
model.addAttribute("upc", upc);
model.addAttribute("duplicateProduct", true); // trigger for duplicate product
}
return "management";
}
And here is my view:
<div id="menu3"
class="tab-pane fade <c:if test="${activeTab == 3}">in active</c:if>">
<div class="container-fluid" style="padding: 2%;">
<div class="row">
<div class="col-md-12"
style="padding-left: 15%; padding-right: 15%;">
<c:if test="${productCreated}">
<div class="alert alert-success fade in">
<a href="#" class="close" data-dismiss="alert"
aria-label="close">×</a> <strong>Success!</strong>
Product has been created!
</div>
</c:if>
<c:if test="${duplicateProduct}">
<div class="alert alert-warning fade in">
<a href="#" class="close" data-dismiss="alert"
aria-label="close">×</a> <strong>Oh no!</strong>
Product with the UPC ${upc} already exists!
</div>
</c:if>
<c:if test="${invalidFormat}">
<div class="alert alert-warning fade in">
<a href="#" class="close" data-dismiss="alert"
aria-label="close">×</a> <strong>Oops!</strong>
Invalid UPC format!
</div>
</c:if>
<form
action="${pageContext.request.contextPath}/manager/createProduct"
method="post">
<div class="form-group">
<label for="Name">Name </label> <input type="text" name="name"
class="form-control" required />
</div>
<div class="form-group">
<label for="UPC">UPC </label> <input type="number" name="upc"
class="form-control" required />
</div>
<div class="form-group">
<div class="form-group">
<label for="category">Category</label> <select
class="form-control" name="category" required>
<option selected disabled value="">SELECT CATEGORY</option>
<c:forEach items="${categories}" var="item">
<option>${item.getName()}</option>
</c:forEach>
</select>
</div>
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" rows="5" name="description"></textarea>
</div>
<div class="form-group">
<label for="price">Price </label> <input type="number"
name="price" class="form-control" required />
</div>
<div class="form-group">
<label for="stock">Stock </label> <input type="number"
name="stock" class="form-control" required />
</div>
<button type="submit" class="btn btn-primary">Add
product</button>
</form>
</div>
</div>
</div>
</div>
Is there a better of doing this other than sending boolean triggers?
You could use Spring BindingResult. This is typical filled with the result of Binding and Validation results. But you can also add errors by hand.
But first you need to refactor your code, so that you use an single command/form-backing object instead of all the #Param values
public class CreateProductCommand {
private String name;
private String upc;
private String categoryName;
.... //other fields
public CreateProductCommand (){} //parameter less conturctor
Getter+Setter
}
Controller
#RequestMapping("/createProduct")
public ModelAndView createProduct(CreateProductCommand createProductCommand, BindingResult bindingResult) //Binding result must be the parameter direct next to the object that should been validated!!!
{
if (someustomValidationForUcpFail()) {
bindingResult.rejectValue("upc", //the field name of the invalid field
"error.Message.Key",
"Default Error Message");
}
if (bindingResult.hasErrors()) {
ModelMap model = new ModelMap();
model.add("createProductCommand", createProductCommand);
return new ModelAndView("createForm", model)
} else {
Product product = ...
return new ModelAndView("showProduct", "product", product)
}
}
jsp:
You need to use springs form and input tag:
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:springForm="http://www.springframework.org/tags/form"
version="2.0">
....
<springForm:form action="<c:url value="/manager/createProduct">" method="POST" modelAttribute="createProductCommand">
<springForm:input path="name"/> <form:errors path="name" />
<springForm:input path="ucp"/> <form:errors path="ucp" />
....
</springForm:form>
....

Laravel 5.3 - 500 internal error when saving a new Eloquent model

When trying to create a new instance of my model Apartment I get a 500 (Internal Server Error). I have other /create/ routes that I use to create new instance of my models and they work properly and they're set up same as ApartmentController#create, but for some weird reason it doesn't work.
ApartmentController#create
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$addresses = Address::all();
return view('address/create')->with('addresses', $addresses);
}
ApartmentController#store
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$address = new Address();
$this->authorize('create', $address);
$validator = Validator::make($request->all(), [
'building_number' => 'required|integer',
'street' => 'required|string',
]);
if ($validator->fails()) {
return redirect('addresses/create')
->withErrors($validator)
->withInput();
}
$address->building_number = $request->building_number;
$address->street = $request->street;
$address->save();
return redirect('addresses/create');
}
View apartment/create
<div class="col-md-6">
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form class="form-horizontal" method="POST" action="{{ action("ApartmentController#store") }}">
<fieldset>
<!-- Form Name -->
<legend>Register a new apartment</legend>
{{ csrf_field() }}
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="address_id">Address</label>
<div class="col-md-4">
<select id="address_id" name="address_id" class="form-control">
#foreach($addresses as $address)
<option value="{{$address->id}}">{{$address->street}} {{$address->building_number}}</option>
#endforeach
</select>
<span class="help-block">Apartments building number</span>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="apartment_number">Apartment Number</label>
<div class="col-md-4">
<input id="apartment_number" name="apartment_number" type="text" placeholder="2402" class="form-control input-md" required="">
<span class="help-block">The apartment number</span>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="size">Apartment Size</label>
<div class="col-md-4">
<input id="size" name="size" type="text" placeholder="56qm" class="form-control input-md" required="">
<span class="help-block">The size of the apartment in qm</span>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="living_area_size">Living Area Size</label>
<div class="col-md-4">
<input id="living_area_size" name="living_area_size" type="text" placeholder="23qm" class="form-control input-md" required="">
<span class="help-block">The size of the living area in qm</span>
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-md-4 control-label" for="suitable_for">Suitable For</label>
<div class="col-md-4">
<select id="suitable_for" name="suitable_for" class="form-control">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<span class="help-block">Number of people the apartment is suitable for.</span>
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-md-4 control-label" for="furnished">Furnished</label>
<div class="col-md-4">
<select id="furnished" name="furnished" class="form-control">
<option value="1">Yes</option>
<option value="0">No</option>
</select>
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-md-4 control-label" for="balcony_or_terrace">Balcony or Terrace</label>
<div class="col-md-4">
<select id="balcony_or_terrace" name="balcony_or_terrace" class="form-control">
<option value="none">None</option>
<option value="balcony">Balcony</option>
<option value="terrace">Terrace</option>
</select>
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-md-4 control-label" for="floor">Floor</label>
<div class="col-md-4">
<select id="floor" name="floor" class="form-control">
<option value="ground">Ground</option>
<option value="first">First</option>
<option value="second">Second</option>
<option value="third">Third</option>
</select>
</div>
</div>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-4 control-label" for="description">Description</label>
<div class="col-md-6">
<textarea class="form-control" id="description" name="description"></textarea>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-4 control-label" for="submit"></label>
<div class="col-md-4">
<button id="submit" name="submit" type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</fieldset>
</form>
</div>
<div class="col-md-4">
<legend>Registered Apartments</legend>
#foreach($apartments as $apartment)
<div class="address">
Apartment {{ $apartment->apartment_number }}
<a href="{{ url('/apartments/' . $apartment->id . '/edit') }}"
onclick="event.preventDefault();
document.getElementById('edit-form-{{$apartment->id}}').submit();">
<button class="btn btn-default">Edit</button>
</a>
<form id="edit-form-{{$apartment->id}}" action="{{ url('/apartments/' . $apartment->id . '/edit') }}" method="GET" style="display: none;">
{{ csrf_field() }}
<input type="hidden" name="address_id" value="{{$apartment->id}}">
</form>
<a href="{{ url('/apartments/' . $apartment->id) }}"
onclick="event.preventDefault();
document.getElementById('delete-form-{{$apartment->id}}').submit();">
<button class="btn btn-warning">Delete</button>
</a>
<form id="delete-form-{{$apartment->id}}" method="POST" action="/apartments/{{$apartment->id}}">
{{ csrf_field() }}
{{ method_field('DELETE') }}
</form>
</div>
<br>
#endforeach
</div>
Route web.php
Route::resource('apartments', 'ApartmentController');
apartments table for Apartment model
I tried to catch the exception on the save() method, but nothing is being caught and I still get redirected to /apartments without any Laravel error just Chroms 500 error page.
This is how I tried to catch the error using dwightwatson/validating:
try{
$apartment = new Apartment();
$apartment->apartment_number = $request->apartment_number;
$apartment->size = $request->size;
$apartment->living_area_size = $request->living_area_size;
$apartment->suitable_for = $request->suitable_for;
$apartment->furnished = $request->furnished;
$apartment->balcony_or_terrace = $request->balcony_or_terrace;
$apartment->floor = $request->floor;
$apartment->description = $request->description;
$apartment->address_id = $request->address_id;
$apartment->saveOrFail();
} catch (ValidationException $e) {
$errors = $e->getErrors();
return redirect()->route('apartments.create')
->withErrors($errors)
->withInput();
}
First of all, you Download Fiddler if you haven't already. Fire it up and then trigger the store method again. Fiddler should tell you a great deal about your request and response:
On the left side, you have a list of requests and on the right, you have statistics and inspectors. Under inspectors tab you will see WebView. Click it and you will see the error generated by Laravel.
As for why it might be failing, check if the references are included properly. e.g:
use App\Address;

Resources