Having trouble with updating my model using @angular/http method http.put()
.
The issue is that I just can't update Position at all. I can successfully update any other field and can set any Position when creating with POST.
My angular version is "^4.3.3"
In java my model looks like
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String name;
String email;
String phone;
Date birthDay;
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "position_id")
Position position;
}
Projection:
public interface EmployeeProjection {
Long getId();
String getName();
String getEmail();
String getPhone();
Date getBirthDay();
@Value("#{target.position.name}")
String getPosition();
}
And Position class:
public class Position {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String name;
}
In angular template Position:
<md-select mdInput placeholder="Position"
[(ngModel)]="newEmployee.position">
<md-option *ngFor="let position of positions | async" [value]="position.name">{{ position.name }}
</md-option>
</md-select>
My update method in component:
update() {
let positionName = this.employee.position;
this.positionService.findByName(positionName).subscribe(position => {
this.employee.position = position._links.self.href;
this.employeeService.update(this.employee);
this.employee.position = positionName;
this.employeeService.localStorageService.set('employee', this.employee);
});
}
And in service:
update(employee: Employee) {
this.http.put(employee._links.self.href, employee)
.map((resp: Response) => resp.json())
.subscribe(() => {
this.getAll();
});
return employee;
}
In chrome Request:
{
"name": "Nikolai Morgan",
"id": 1,
"position": "http://localhost:9080/api/positions/5",
"birthDay": "1986-07-01",
"email": "NikolaiMorgan@gmail.com",
"phone": "+380840713229",
"_links": {
"self": {
"href": "http://localhost:9080/api/employees/1"
},
"employee": {
"href": "http://localhost:9080/api/employees/1{?projection}",
"templated": true
},
"position": {
"href": "http://localhost:9080/api/employees/1/position"
}
}
}
But response and preview not contain field Position:
{
"id" : 1,
"name" : "Nikolai Morgan",
"email" : "NikolaiMorgan@gmail.com",
"phone" : "+380840713229",
"birthDay" : "1986-07-01",
"_links" : {
"self" : {
"href" : "http://localhost:9080/api/employees/1"
},
"employee" : {
"href" : "http://localhost:9080/api/employees/1{?projection}",
"templated" : true
},
"position" : {
"href" : "http://localhost:9080/api/employees/1/position"
}
}
}
To update entity that has reference to another one, in Spring Data REST you have to use a link to this entity. For example:
@Entity
class Employee {
//...
String name;
@ManyToOne
Position position;
//...
}
@Entity
class Position {
//...
String name;
//...
}
interface EmployeeRepo extends JpaRepository<Employee, Long> {}
interface PositionRepo extends JpaRepository<Position, Long> {}
First we add a position:
POST http://localhost:9080/api/positions
{
"name": "position1"
}
And get a response like this:
{
"name": "position1",
"_links" : {
"self" : {
"href" : "http://localhost:9080/api/positions/1"
},
"position" : {
"href" : "http://localhost:9080/api/positions/1"
}
}
}
Then add an employee:
POST http://localhost:9080/api/employees
{
"name": "employee1",
"employee": "http://localhost:9080/api/positions/1"
}
Then get a response:
{
"name" : "employee1",
"_links" : {
"self" : {
"href" : "http://localhost:9080/api/employees/1"
},
"employee" : {
"href" : "http://localhost:9080/api/employees/1",
},
"position" : {
"href" : "http://localhost:9080/api/employees/1/position"
}
}
}
So if we need to update position we create a new one, then PUT the employee:
PUT http://localhost:9080/api/employees/1
{
"name": "employee1",
"position": "http://localhost:9080/api/positions/2"
}
Or even PATCH it:
PATCH http://localhost:9080/api/employees/1
{
"position": "http://localhost:9080/api/positions/2"
}