How to post nested json using angular js in form - java

How to POST Item Object using angularjs?
My simple java class:
#Entity
public class ProductionOrder implements Serializable {
#Enumerated(EnumType.STRING)
public Status status;
#Id
#GeneratedValue
private Long id;
#ManyToOne
#JoinColumn(name = "ITEM_ID")
private Item item;
private int plannedQty;
private Date plannedDate;
private String description;
//getters setters enum
My angular controller:
'use strict';
App.controller('PoController', ['$scope', 'PoService', function($scope, PoService) {
var vm = this;
vm.order = {id: null, status: null, item:null , plannedQty: null, plannedDate: '', description:''};
vm.orders = [];
vm.fetchAllOrders = function () {
PoService.fetchAllOrders()
.then(
function (d) {
vm.orders = d;
},
function (errResp) {
console.error('Error while fetching production orders!');
}
);
};
vm.createOrder = function (item) {
PoService.createOrder(item)
.then(
vm.fetchAllOrders,
function (errResponse) {
console.error('Error while creating production order');
}
);
};
vm.fetchAllOrders();
vm.submit = function () {
if (vm.order.id === null) {
console.log('Saving new order', vm.order);
vm.createOrder(vm.order);
} else {
console.log('Sth wrong with adding new order');
}
vm.reset();
};
vm.reset = function () {
vm.order = {id: null, status:null, item: null, plannedQty: null, plannedDate: '', description:''};
$scope.myForm.$setPristine();
};
}]);
And this is my angular service:
'use strict';
App.factory('PoService', ['$http', '$q', function ($http, $q) {
return {
fetchAllOrders: function () {
return $http.get('http://localhost:8080/api/po/all')
.then(
function (response) {
return response.data;
},
function (errResponse) {
console.error('Error while fetching production orders');
return $q.reject(errResponse);
}
);
},
createOrder: function (item) {
return $http.post('http://localhost:8080/api/po/add', item)
.then(
function (res) {
return res.data;
},
function (errRes) {
console.error('Error while adding production order');
return $q.reject(errRes);
}
);
}
};
}]);
In html I have simple form:
<div class="ui main text container", ng-controller="PoController as ctrl">
<form class="ui form" ng-submit="ctrl.submit()" name="myForm">
<h4 class="ui dividing header">Production order information</h4>
<div class="field">
<label> </label>
<div class="two fields">
<div class="field">
<input type="text" ng-model="ctrl.order.id" placeholder="Production order id">
</div>
<div class="field">
<input type="text" ng-model="ctrl.order.item" placeholder="Item id">
</div>
</div>
</div>
<h4 class="ui dividing header">Status:</h4>
<select class="ui dropdown" ng-model="ctrl.order.status">
<option value="CREATED">CREATED</option>
<option value="PLANNED">PLANNED</option>
<option value="DONE">DONE</option>
</select>
<h4 class="ui dividing header">Planning information</h4>
<div class="field">
<label> </label>
<div class="two fields">
<div class="field">
<input type="text" ng-model="ctrl.order.plannedQty" placeholder="Quantity">
</div>
<div class="field">
<input type="text" ng-model="ctrl.order.plannedDate" placeholder="Enter date RRRR-MM-DD">
</div>
</div>
</div>
</br>
<div class="field">
<label>Description</label>
<textarea ng-model="ctrl.order.descritpion"></textarea>
</div>
<div class="asbutton" id="button">
<input type="submit" value="Save" class="ui primary button" ng-disabled="myForm.$invalid">
<button class="ui button" type="button" ng-click="ctrl.reset()" ng-disabled="myForm.$pristine">
Reset
</button>
</div>
</form>
</div>
And when i type for example: 1. It means I want to create realtion with item with 1 id. In Terminal I see error:
2016-06-12 16:06:13.906 WARN 10057 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not instantiate value of type [simple type, class com.prod.domain.Item] from String value ('2'); no single-String constructor/factory method
at [Source: java.io.PushbackInputStream#2b8fb852; line: 1, column: 25] (through reference chain: com.prod.domain.ProductionOrder["item"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.prod.domain.Item] from String value ('2'); no single-String constructor/factory method
at [Source: java.io.PushbackInputStream#2b8fb852; line: 1, column: 25] (through reference chain: com.prod.domain.ProductionOrder["item"])
How could I POST nested json similar to this:
item: {id: 6}

Related

I passed the variable of Date type to Ajax and received it back to the controller, but the value changed

I want to receive the date through the date picker and put it in an object that stores reservation information(RentalPlacesVo).
I received the date from the reservation form and also confirmed that the controller fits the vo object well (even the datatype in rental_date was java.sql.Date)
After making the payment, I sent it to Ajax to include it with other information, and in the process of processing Ajax, I confirmed that 2022-07-23 was changed to 1992. It seems that the date has not been properly stored in the date type column of the db since the date has been changed to 1992.
I need to store data of DATE type on vo object, how can I get it?
Details of the error are as follows.
WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.sql.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [#org.springframework.web.bind.annotation.RequestParam java.sql.Date] for value '1992'; nested exception is java.lang.IllegalArgumentException
RentalPlacesVo
package com.joinus.domain;
import java.sql.Date;
import lombok.Data;
#Data
public class RentalPlacesVo {
private int rental_places_no;
private String reservation_no;
private int club_no;
private int member_no;
private int partner_place_no;
private int payment_no;
private Date rental_date;
private int rental_time_no;
private int rental_status;
}
reservationForm.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# include file="../include/header.jsp"%>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey="appkey"&libraries=services"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery#3.6.0/dist/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script type="text/javascript">
// Calendar
var config = {
dateFormat : 'yy-mm-dd',
showOn : "button",
buttonText : "선택",
prevText : '이전 달',
nextText : '다음 달',
monthNames : ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'],
monthNamesShort : ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'],
dayNames : ['일','월','화','수','목','금','토'],
dayNamesShort : ['일','월','화','수','목','금','토'],
dayNamesMin : ['일','월','화','수','목','금','토'],
yearSuffix : '년',
minDate : 1
}
$(function(){
$("input[name='rental_date']").datepicker(config);
});
$(document).ready(function(){
$(':button').attr('class','btn btn-primary');
$('#subBtn').click(function(){
// var date = $('#rental_date').val(); // 2022-07-23
if($('#rental_date').val() == ''){
$('#rental_date').focus();
return false;
}
if($('#rental_time_no').val() == ''){
$('#rental_time_no').focus();
return false;
}
if($('#memberCnt').val() == ''){
$('#memberCnt').focus();
return false;
}
if($('#memberCnt').val() > 20){
alert('Max MemberCnt : 20');
$('#memberCnt').focus();
return false;
}
});
});
</script>
<div class="container-xxl py-5">
<div class="container" style="color: black;">
<div class="row g-5">
<h1 id="partnerPlaceName">${partnerPlace.partner_place_name }</h1>
<div style="width: 70%;">
<img style="width: 95%; max-height: 550px;" src="${PageContext.request.contextPath }/resources/upload/partner_place/${partnerPlace.partner_place_image}">
<div style="margin-top: 3em;">
<pre class="boardContent">${partnerPlace.partner_place_content }</pre>
</div>
<div style="margin-bottom: 16px;">
<i class="fa fa-phone-alt me-3" aria-hidden="true"></i>${partnerPlace.partner_place_tel }
</div>
<div id="partnerPlaceAddr" style="margin-bottom: 16px;">
${partnerPlace.partner_place_address }
</div>
</div>
<div style="width: 30%; border: 1px solid #32C36C; padding-top: 1em; height: 70%;">
<form name="fr" action="" method="post">
<input type="hidden" name="partner_place_no" value="${partner_place_no }">
<input type="hidden" name="partner_place_name" value="${partnerPlace.partner_place_name }">
<input type="hidden" name="partner_place_price" value="${partnerPlace.partner_place_price }">
<div>
<div style="font-size: x-large; float: left;">
${partnerPlace.partner_place_name }
</div>
<div style="color: #32C36C; text-align: right; margin-bottom: 2em;">
<span style="font-size: x-large;">
<fmt:setLocale value="ko_KR"/><fmt:formatNumber type="currency" value="${partnerPlace.partner_place_price }" />
<br>
</span>
<span style="color: #9B9B9B;"> /hour</span>
</div>
</div>
<div>
MemberCnt <input type="number" class="form-control" id="memberCnt" name="memberCnt" max="20" required>
</div>
<script type="text/javascript">
var memberCnt = 0;
var totalPrice = 0;
$('#memberCnt').blur(function(){
memberCnt = $('#memberCnt').val();
totalPrice = memberCnt * ${partnerPlace.partner_place_price} * 2
document.getElementById("seePrice").innerHTML = totalPrice.toLocaleString();
$('#payment_price').val(totalPrice);
});
</script>
<!-- Date -->
<div style="margin-bottom: 2em;">
Select Date (Click button)
<input class="form-control" id="rental_date" name="rental_date" autocomplete="off" readonly style="background-color: white;">
</div>
<!-- Time -->
<div style="margin-bottom: 2em;">
Time
<select class="form-select" id="rental_time_no" name="rental_time_no">
<option value="">Select Time</option>
<option value="1">10:00~12:00</option>
<option value="2">12:00~14:00</option>
<option value="3">14:00~16:00</option>
<option value="4">16:00~18:00</option>
<option value="5">18:00~20:00</option>
<option value="6">20:00~22:00</option>
</select>
</div>
<!-- TotalPrice -->
<div>
TotalPrice<br>
<span id="seePrice"></span>
<input type="hidden" id="payment_price" name="payment_price">
</div>
<div class="payBtn">
<input type="submit" class="btn btn-primary rounded-pill py-3 px-5" id="subBtn" value="pay">
</div>
</form>
</div>
</div>
</div>
</div>
<%# include file="../include/footer.jsp"%>
Controller
#RequestMapping(value = "/partnerPlaces/{partner_place_no}", method = RequestMethod.POST)
public String partnerPlaceContentPost(PartnerPlacesVo partnerplacevo ,PaymentsVo paymentvo,
RentalPlacesVo rentalplacevo, Model model, #RequestParam("rental_time_no") int rentaltimeno,
HttpSession session,#RequestParam("payment_price") int payment_price) {
log.info(" partnerPlaceContentPost() 호출");
// log.info("#####rental_date : "+rental_date); // 2022-07-23
log.info("rentalplacevo : "+rentalplacevo.getRental_date());
log.info("rental_date type: "+rentalplacevo.getRental_date().getClass().getName()); // java.sql.Date
String ppname = partnerplacevo.getPartner_place_name();
model.addAttribute("ppname", ppname);
model.addAttribute("payment_price", payment_price);
log.info("ppname, totalprice: "+ppname+payment_price);
MembersVo vo = (MembersVo)session.getAttribute("member");
model.addAttribute("members", vo);
model.addAttribute("rental_time_no", rentaltimeno);
model.addAttribute("payment", paymentvo);
model.addAttribute("rentalplacevo", rentalplacevo);
return "/rental/payment";
}
payment.jsp (use API)
if(rsp.success){
$.ajax({ //verify
type : 'POST',
url : '${PageContext.request.contextPath }/rental/verifyIamport/'+rsp.imp_uid
}).done(function(result){
// rsp.paid_amount와 result.response.amount(서버 검증) 비교 후 로직 실행
if(rsp.paid_amount === result.response.amount){
alert("success pay varify"); console.log("success pay varify");
var rental_date = ${rentalplacevo.rental_date};
alert("rental_date : "+rental_date); // 1992
$.ajax({
url : '${PageContext.request.contextPath }/rental/partnerPlaces/'+${payment.partner_place_no}+'/payment',
type :'POST',
data :{'partner_place_price':${payment.partner_place_price},
'rental_date':${rentalplacevo.rental_date},
'payment_price':${payment_price},
'rental_time_no':${rental_time_no}},
dataType: 'json',
success: function(paymentvo){
alert('Success store all data');
setTimeout(function(){
location.href="${PageContext.request.contextPath }/"
},5000);
}
});
}
}).fail(function(error){
console.log("fail to store data");
});
}else{
alert('fail'+'errorCode : '+rsp.error_code+'errMsg : '+rsp.error_message);
}
Controller - I can't get over here.
#ResponseBody
#RequestMapping(value="/verifyIamport/{imp_uid}")
public IamportResponse<Payment> paymentByImpUid(
Model model, Locale locale, HttpSession session
, #PathVariable("imp_uid") String imp_uid ) throws IamportResponseException, IOException{
log.info("paymentByImpUid");
return api.paymentByImpUid(imp_uid);
}
#ResponseBody
#RequestMapping(value ="/partnerPlaces/{partner_place_no}/payment",method=RequestMethod.POST)
public PaymentsVo payment( Model model,
#RequestParam("partner_place_price") int partner_place_price,
#RequestParam("rental_date") Date rental_date,
#RequestParam("payment_price") int payment_price,
#RequestParam("rental_time_no") int rental_time_no,
#PathVariable("partner_place_no") int partner_place_no,
RentalPlacesVo rentalplacevo, PaymentsVo paymentvo,HttpSession session){
log.info("Vo Info . paymentvo : "+paymentvo);
log.info("Vo Info . RentalPlacesVo : "+rentalplacevo);
log.info("rental_date : "+rental_date);
// log.info("rentdate dataType : "+rentdate.getClass().getName());
// reservationNum (Date-place_no)
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Calendar cal = Calendar.getInstance();
java.util.Date date = cal.getTime();
String rsNum = sdf.format(date)+"-"+partner_place_no;
log.info(reservationNum"+rsNum);
paymentvo.setReservation_no(rsNum);
MembersVo mvo = (MembersVo)session.getAttribute("member");
paymentvo.setMember_no(mvo.getMember_no());
paymentvo.setPartner_place_no(partner_place_no);
paymentvo.setPartner_place_price(partner_place_price);
paymentvo.setPayment_status(1);
Integer pay = rentalService.pay(paymentvo);
rentalplacevo.setPayment_no(paymentvo.getPayment_no());
if(pay == 1) {
log.info("success");
}else {
log.info("fail");
}
rentalplacevo.setClub_no(46);
rentalplacevo.setMember_no(mvo.getMember_no());
rentalplacevo.setRental_places_no(partner_place_no);
rentalplacevo.setReservation_no(rsNum);
rentalplacevo.setRental_date(rental_date); // date
rentalplacevo.setRental_time_no(rental_time_no); // time
rentalplacevo.setRental_status(1);
rentalService.place(rentalplacevo);
log.info("rentalPlace : "+rentalplacevo);
return paymentvo;
}
Use date related annotations on the date field.
#Temporal(TemporalType.DATE)
#DateTimeFormat(pattern = "yyyy/MM/dd")
private Date rental_date;
Best practice:
Also it is recommended to use camel case standard for pojo entity class variables like rentalDate.

Bind Form Data as JSON String/String Array to Request Params In String

I have a form which I would like to send to my controller via ajax:
<div class="row">
<label for="username" class="col-sm-2 col-form-label my-auto">Username:</label>
<div class="col-sm-10 my-auto">
<input type="text" class="form-control" id="username" name="username">
</div>
</div>
<div class="row">
<label for="password" class="col-sm-2 col-form-label my-auto">Password:</label>
<div class="col-sm-10 my-auto">
<input type="text" class="form-control" id="password" name="password">
</div>
</div>
<div class="row" id="ratingRow">
<label for="adminFoci" class="col-sm-2 col-form-label my-auto">User Rating:</label>
<div class="col-sm-auto my-auto">
<select class="selectpicker" multiple data-live-search="true" name="adminFoci" id="adminFoci" title="Choose Foci">
<c:forEach items="${foci}" var="focus">
<option name="${focus.focusName}" value="">${focus.focusName}</option>
</c:forEach>
</select>
</div>
<div class="col-sm my-auto">
<input type="text" class="form-control" id="rating" name="rating">
</div>
<div class="col-sm-auto my-auto" id="ratingButtonRow">
<div class="btn btn-info btn-sm" id="adminAddGroup">Add Rating</div>
</div>
</div>
<div class="row">
<label for="adminUserGroups" class="col-sm-2 col-form-label my-auto">User's Groups:</label>
<div class="col-sm-auto my-auto">
<select class="selectpicker" multiple data-live-search="true" id="adminUserGroups" name="groups" title="Choose Groups">
<c:forEach items="${groups}" var="group">
<option name="${group.groupName}" value="${group.groupName}">${group.groupName}</option>
</c:forEach>
</select>
</div>
</div>
<div class="row">
<label class="col-sm-2 col-form-label my-auto">User's Roles:</label>
<div class="col-sm-10 my-auto">
<select class="selectpicker" multiple data-live-search="true" id="adminUserRoles" name="roles" title="Choose Roles">
<c:forEach items="${user.roles}" var="role">
<option name="${role.name}" value="${role.name}">${role.name}</option>
</c:forEach>
</select>
</div>
</div>
I catch the form submit and serialize the form data:
$("#modalForm").submit(function(e){
e.preventDefault();
var form = $(this);
$.ajax({
type: "POST",
url: form.attr('action'),
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify($(this).serializeArray()),
success: function(data)
{
table.row('.selected').ajax.reload();
}
});
});
I then try to bind data of the json string array to request params in my controller:
#PostMapping(value="/AdminCreateUser", consumes = MediaType.APPLICATION_JSON_VALUE)
public void createUser(#RequestParam String username, #RequestParam String password, #RequestParam (required = false) String[] roles,
#RequestParam (required = false) String[] groups){
User user = new User(username, password);
if(roles != null){
Set<Role> roleList = roleService.findRoles(roles);
if(roleList.size() > 0){
user.setRoles(roleList);
}
}
if(groups != null){
Set<Group> groupList = groupService.findGroups(groups);
for(Group group: groupList){
group.addMember(user);
groupRepository.save(group);
}
}
userRepository.save(user);
}
However I get Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'username' is not present]. Does Jackson not bind matching elements of the json string array to the request parameters? If not, how do I do this? I want to save myself the effort of sending each form field as separate data
The output of serialize array will be,
[
{
"name" : "username",
"value" : "test"
},...
]
Then change the java code as,
public void createUser(#RequestBody String body){
Convert string to JSONObject and handle it as JSON. Then this will work.
If you want to handle with Request Param.
Change the content-type to multipart/form-data and post it directly to the API.
There are two way.
By using application/json
Modify your js code like this.
$("#modalForm").submit(function(e){
e.preventDefault();
var form = $(this);
//convert form data to json array of Object(name value pair)
data = []
var x = $(this).serializeArray();
$.each(x, function(i, field){
var name = field.name; var value = field.value;
data[i] = {name : value};
});
$.ajax({
type: "POST",
url: form.attr('action'),
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
success: function(data)
{
table.row('.selected').ajax.reload();
}
});
});
Modify your controller
public void createUser(#RequestBody CreateUserDto createUserRequest){
If you want to use request param change content-type to multipart/form-data.

ERROR TypeError: Cannot set property 'name' of undefined

I'm trying update project and i'm facing with this problem "ERROR TypeError: Cannot set property 'name' of undefined"
Here's update-project.thml:
<!doctype html>
<html class="no-js" lang="en">
<head>
...
</head>
<body ng-app="dateInputExample">
...
<div class="container custom-container">
<form [formGroup]="updateProjectForm" (ngSubmit)="updateProject(updateProjectForm.value)" class="ui form"
style="margin-left: 3%; width: 30%;">
<h1 id="projectTitle">Update Project</h1>
<div style="margin: 0 auto;">
<div style="margin-top: 100px;">
<div class="field">
<label>Project Name</label>
<input type="text" formControlName="projectName" class="form-control" name="projectName"
[(ngModel)]="projectData.name" placeholder="Your project name"
[ngClass]="{'is-invalid' : submitted && updateProjectForm.controls.projectName.errors}"/>
<div *ngIf="submitted && updateProjectForm.controls.projectName.errors" class="err_msg form-text">
<p class="err-msg">Project Name is required</p>
</div>
</div>
<div class="field" style="margin-top: 5%;">
<label>Project Description</label>
<textarea rows="4" cols="50" formControlName="projectDescription" [(ngModel)]="projectData.description"
class="form-control"
placeholder="Your project description"></textarea>
</div>
<label>Expiry Date</label>
<div>
<input type="date" formControlName="expiryDate" class="form-control" [(ngModel)]="dateInForm"
placeholder="expiryDate"
min="2019-08-07" max="2020-12-31" required/>
</div>
<div class="form-panel ui-helper-hidden">
<label>Budget</label>
<input type="number" formControlName="budget" maxlength="16" placeholder="Budget"
[(ngModel)]="projectData.budget">
</div>
<div class="field" style="margin-top: 5%;" *ngIf="showSkills">
<label>Skills</label>
<div class="ui segment">
<app-skills-multiselect>
</app-skills-multiselect>
</div>
</div>
<div class="field" style="margin-top: 5%;" *ngIf="showProjectType">
<label>Project Type</label>
<div class="ui segment">
<app-pt-multiselect></app-pt-multiselect>
</div>
</div>
<div class="field" style="margin-top: 5%;">
<button type="submit" class="ui primary button">Update</button>
<a routerLink="/back" class="ui button">Cancel</a>
</div>
</div>
</div>
</form>
</div>
...
</body>
</html>
Here's update-project.ts
...
export class UpdateProjectComponent implements OnInit {
constructor(private formBuilder: FormBuilder, private projectService: ProjectService, private activatedRoute: ActivatedRoute,
private rout: Router, private datePipe: DatePipe) {
this.submitted = false;
this.router = rout;
this.updateProjectForm = this.formBuilder.group({
projectName: ['', [Validators.required]],
...
});
}
saved = false;
submitted: boolean;
projectName: string;
router: Router;
project: Project;
projectData: any = {};
dateInForm: string;
showMsg = false;
showErrMsg = false;
showSkills = false;
showProjectType = false;
skill = [];
selectedType = [];
#ViewChild(PrMultiselectComponent, { static: false })
private prMultiselectComponent: PrMultiselectComponent;
#ViewChild(SkillsMultiselectComponent, { static: false })
private skillMultiselectComponent: SkillsMultiselectComponent;
id = this.activatedRoute.snapshot.params.id;
updateProjectForm: any;
save() {
this.saved = true;
}
ngOnInit() {
this.projectService.getProjectById(this.id).subscribe(data => {
this.projectData = data;
console.log(this.projectData);
// Show selected skills
this.skillMultiselectComponent.selectedItems = this.projectData.skillSet.map(this.skillMultiselectComponent.parseSkillsList);
console.log(this.skillMultiselectComponent);
// Show selected Type
this.selectedType.push({ id: this.projectData.projectType.id,
itemName: this.projectData.projectType.name });
this.prMultiselectComponent.selectedTypeItems = this.selectedType;
// TODO don't show expiry date
// this.dateInForm = this.datePipe.transform(this.projectData.expiryDate, 'MM-dd-yyyy');
// console.log(this.dateInForm);
});
this.showSkills = true;
this.showProjectType = true;
}
canDeactivate(): boolean | Observable<boolean> {
if (!this.saved) {
return confirm('Are yo sure you want to left this page without saving information?');
} else {
return true;
}
}
updateProject(projectDataFromForm) {
if (window.confirm('Are you sure, you want to update?')) {
console.log('in updateProject()');
console.log(projectDataFromForm);
this.submitted = true;
this.project.name = projectDataFromForm.projectName;
this.project.description = projectDataFromForm.projectDescription;
this.project.expiryDate = projectDataFromForm.expiryDate;
this.project.budget = projectDataFromForm.budget;
// this.project.projectTypeId = this.idprojecttype;
this.project.projectTypeId = this.prMultiselectComponent.getSelectedItems();
this.project.skills = this.skillMultiselectComponent.getSelectedItems();
// var data = this.selectedItems.map(t=>t.id);
this.projectService.updateProject(this.id, this.project).subscribe(
data => {
this.updateProjectForm.reset();
this.showMsg = true;
// this.router.navigate(['/home']);
console.log('Successfully updated!');
},
err => {
this.showErrMsg = true;
console.log('Update failed!');
});
}
}
}
ng:///AppModule/UpdateProjectComponent.ngfactory.js:94 ERROR TypeError: Cannot set property 'name' of undefined
at UpdateProjectComponent.updateProject (:4200/main.js:2678)
at Object.eval [as handleEvent] (ng:///AppModule/UpdateProjectComponent.ngfactory.js:111)
at handleEvent (:4200/vendor.js:101276)
at callWithDebugContext (:4200/vendor.js:102894)
at Object.debugHandleEvent [as handleEvent] (:4200/vendor.js:102530)
at dispatchEvent (:4200/vendor.js:88996)
at :4200/vendor.js:90893
at SafeSubscriber.schedulerFn [as _next] (:4200/vendor.js:94272)
at SafeSubscriber.__tryOrUnsub (:4200/vendor.js:193518)
at SafeSubscriber.next (:4200/vendor.js:193457)
If I deleted 'name' field showed the same problem with description....
Thanks for the help!
Reason for Error :
[(ngModel)]="projectData.name" , if you are using [(ngModel)] 2-way data binding it will need some initial values, but it gets undefined
1st Solution *ngIf='projectData':
<div class="container custom-container">
<form [formGroup]="updateProjectForm" (ngSubmit)="updateProject(updateProjectForm.value)" class="ui form"
style="margin-left: 3%; width: 30%;">
<h1 id="projectTitle">Update Project</h1>
<div style="margin: 0 auto;" *ngIf='projectData'> <!-- HERE -->
<div style="margin-top: 100px;">
<div class="field">
<label>Project Name</label>
<input type="text" formControlName="projectName" class="form-control" name="projectName"
[(ngModel)]="projectData.name" placeholder="Your project name"
[ngClass]="{'is-invalid' : submitted && updateProjectForm.controls.projectName.errors}" />
<div *ngIf="submitted && updateProjectForm.controls.projectName.errors" class="err_msg form-text">
<p class="err-msg">Project Name is required</p>
</div>
</div>
...
</div>
</div>
</form>
</div>
2nd Soltuion (Provide some initial value):
project: Project = {
..., // other values too
name : ''
};
3rd option, remove [(ngModel)] 2-way data binding from all:
this.project.name = projectDataFromForm.projectName;
this.project.description = projectDataFromForm.projectDescription;
this.project.expiryDate = projectDataFromForm.expiryDate;
this.project.budget = projectDataFromForm.budget;
// this.project.projectTypeId = this.idprojecttype;
this.project.projectTypeId = this.prMultiselectComponent.getSelectedItems();
this.project.skills = this.skillMultiselectComponent.getSelectedItems();
// --- Patch value will set values in your form ---
this.updateProjectForm.patchValue(this.project); // <---- HERE
I think your problem is caused by this line:
this.project.name = projectDataFromForm.projectName;
because as far as I can see, you don't instantiate your Project object.
In ngOnInit, try adding
this.project = new Project(/* include any necessary data here for the Project constructor */);

Ajax call error in Spring MVC

I have a form where I add the customer's informations. This informations are passed to #Controller by an Ajax call.
Customer.java
public class Customer {
private String name;
private String fiscalCode;
private String vat;
private String telephone;
private String webSite;
private String sector;
private String address;
//Below there are constructor and getter/setter methods
Above the form there is:
<c:set var="serverUrl" value="${pageContext.servletContext.contextPath}"/>
<script>
var serverUrl = '${serverUrl}';
</script>
Form in the jsp
<form>
<div class="form-group">
<input id="nameCustomer" class="form-control" type="text" placeholder="Name customer">
</div>
<div class="form-group">
<input id="fiscalCode" class="form-control" type="text" placeholder="Fiscal code">
</div>
<div class="form-group">
<input id="vat" class="form-control" type="number" placeholder="VAT number (if available)">
</div>
<div class="form-group">
<input id="telephone" class="form-control" type="tel" placeholder="Phone number">
</div>
<div class="form-group">
<input id="website" class="form-control" type="email" placeholder="Customer's Website (if available)">
</div>
<div class="form-group">
<input id="address" class="form-control" type="text" placeholder="Customer's Address">
</div>
<div class="form-group">
<input id="sector" class="form-control" type="text" placeholder="Sector">
</div>
<button id="createCustomer" type="button" class="btn btn-success" style="text-align: center">Save</button>
</form>
Ajax call (the link to this ajax call code is below the form)
$("#createCustomer").click(function () {
alert("createCustomer");
alert(serverUrl);
var nameCustomer = $("#nameCustomer").val();
var fiscalCode = $("#fiscalCode").val();
var vat = $("#vat").val();
var telephone = $("#telephone").val();
var website = $("#website").val();
var address = $("#address").val();
var sector = $("#sector").val();
alert(address);
$.ajax({
url: serverUrl + "/addCustomer",
dataType: 'text',
data: {name: nameCustomer,
fiscalCode: fiscalCode,
vat: vat,
telephone: telephone,
webSite: website,
address: address,
sector: sector},
success: function (data) {
$("#customerAdded").modal('show');
},
error: function (xhr, error, exception) {
$("#errorCustomer").modal('show');
}
});
});
Controller
#Controller
public class CustomerController {
#RequestMapping("addCustomer")
public void addCustomer(#ModelAttribute Customer customer){
JOptionPane.showMessageDialog(null, customer.toString());
}
Chrome gives me this error:
http://localhost:8080/ReportVisitaWeb/addCustomer?name=gdg&fiscalCode=dfgdfg&vat=&telephone=dfgg&webSite=dfggf&address=dfgddf&sector=gdg Failed to load resource: the server responded with a status of 404 (Not Found)
Why?
You are not mapping the request "addCustomer" correctly. Edit your CustomerController as below:
#Controller
public class CustomerController {
#RequestMapping("/addCustomer")
public void addCustomer(#ModelAttribute Customer customer){
JOptionPane.showMessageDialog(null, customer.toString());
}
}

Edit action returns null

I'm new to Struts2 framework and I found a problem when I try to edit an object.
The code of my modification action:
#Action(value = "modifyServer", results = {
#Result(name = "success", location = Location.MAIN_PAGE),
#Result(name = "error", location = Location.LOGIN_PAGE) })
public String modifyServer() {
em = DbConnexion.getEntityManager().createEntityManager();
String id=request.getParameter(sssid);
logger.info("id serveur = "+request.getParameter("id"));
try {
em.getTransaction().begin();
Simserver server = em.find(Simserver.class, id);
server.setSssServer(request.getParameter("sssServer"));
server.setSssIp(request.getParameter("sssIp"));
server.setSssPort(request.getParameter("sssPort"));
em.getTransaction().commit();
System.out.println("modification done !!!");
em.close();
return SUCCESS;
} catch (Exception e) {
return ERROR;
}
}
The JSP:
<form class="form-horizontal" action="modifyServer" role="form"
name="form_message" method="get">
<div id="elmsg"></div>
<div class="panel panel-info">
<div class="panel-heading expand" id="second-level">
<h6 class="panel-title">Modification du Serveur</h6>
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-sm-2 control-label"> Id du Serveur : <span
class="mandatory">*</span></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="sssId"
disabled="disabled" id="sssId"
value="<s:property value="#request.curentserver.sssId" />">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"> Nom du Serveur : <span
class="mandatory">*</span></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="sssServer"
id="sssServer"
value="<s:property value="#request.curentserver.sssServer" />">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"> Adresse IP : <span
class="mandatory">*</span></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="sssIp" id="sssIp"
value="<s:property value="#request.curentserver.sssIp" />" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"> Port : <span
class="mandatory">*</span></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="sssPort" id="sssPort"
value="<s:property value="#request.curentserver.sssPort" />" />
</div>
</div>
<div class="form-actions text-right">
<button type="submit" value="Envoyer" class="btn btn-success"
>Modifier le serveur</button>
<a role="button" href="gestionServeurList" class="btn btn-danger">Retour
à la list des serveurs</a>
</div>
When I execute my action the request.getParameter returns null.
I think the issue is in the parameter!
There are issues with code:
In Java code you are trying to print a request parameter with name as "id" instead of "sssId".
Also you are trying to use a variable called "sssid" that is no where defined in your question.
String id=request.getParameter(sssid);
logger.info("id serveur = "+request.getParameter("id"));
In JSP the sssId element is disabled, when you submit a form the disabled elements are ignored.
<input type="text" class="form-control"
name="sssId" disabled="disabled" id="sssId"
value="<s:property value="#request.curentserver.sssId" />">
So to get its value, create a hidden element in your jsp and on form submission update the hidden element with the required value using JavaScript.
<input type="hidden" name="sssId" value=""/>
In Javascript it will be like:
document.getElementById("sssId").value = 123; // Give value here
document.getElementById("myForm").submit(); // Give an Id to your form, say "myForm"
Finally the Action code looks like this :
public class MyAction extends ActionSupport implements ServletRequestAware {
#Action(value = "modifyServer", results = {
#Result(name = "success", location = Location.MAIN_PAGE),
#Result(name = "error", location = Location.LOGIN_PAGE) })
public String modifyServer() {
String id = request.getParameter("sssId");
System.out.println("id serveur = " + id);
return null;
}
private HttpServletRequest request;
#Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
If the input element has disabled="disabled" attribute it won't include as parameter when your form is submitted. Also rename the input element name that correspond to a parameter name. Struts2 getter/setter can be used to populate the action bean.
public void setSssId(String id){
this.id = id;
}
I'd suggest checking value of sssId being passed to the action through javascript.
<button onclick='javascript:submitMyForm();' type="button" value="Envoyer" class="btn btn-success"
>Modifier le serveur</button>
write the following javascript
function submitMyForm(){
var sssIdElement = document.getElementById("sssId");
document.form_message.action = "modifyServer.action?sssId="+sssIdElement;
document.form_message.submit();
}

Categories