I have a Spring entity, Agent, which contains an Agency. When adding a new agent I have to also pass the agency he works at, but as an object. The backend code works just fine, but when I try to add an agent using an Angular form, I haven't managed to find how to pass the agency object to it. I'm only saving the id of an agency in the database, but I have to specify the whole object when creating the entity. This is the agent entity:
@Entity
@Builder
@Getter
@Setter
public class Agent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String firstName;
@Column(nullable = false)
private String lastName;
private String phone;
@Column(nullable = false)
private String email;
@ManyToOne
@JoinColumn(name = "agency_id", referencedColumnName = "id", nullable = false)
@JsonIgnore
private Agency agency;
}
This is the DTO:
@Getter
@Setter
@Builder
public class AgentDto {
private Integer id;
@NotNull
private String firstName;
@NotNull
private String lastName;
private String phone;
@NotNull
@Email
private String email;
private Agency agency;
}
This is the method to save an agent, located in the AgentService (repo is the injection of a JpaRepository, so I'm using the standard save method):
public AgentDto save(AgentDto agentDto) {
Agent agent = mapper.mapToEntity(agentDto);
Agent agentSaved = repo.save(agent);
return mapper.mapToDto(agentSaved);
}
The controller only contains a method call:
@PostMapping
public AgentDto save(@RequestBody AgentDto agentDto) {
return service.save(agentDto);
}
Now, getting to Angular, this is my agent model:
import { Agency } from "./agency";
export interface Agent {
id: number;
firstName: string;
lastName: string;
email: string;
phone: string;
agency: Agency;
}
This is the method used in the agent service:
addAgent(model: any) {
return this.http.post(this.baseUrl + 'agents', model);
}
This is the typescript in my "add-agent" component:
import { Location } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AgentService } from '../_services/agent.service';
@Component({
selector: 'app-create-agent',
templateUrl: './create-agent.component.html',
styleUrls: ['./create-agent.component.css']
})
export class CreateAgentComponent implements OnInit {
model: any = {};
agencies: Agency[] = [];
constructor(private agentService: AgentService, private router: Router, private _location: Location) { }
ngOnInit(): void { this.loadAgencies(); }
loadAgencies() {
this.agencyService.loadAgencies().subscribe(
agencies => {
this.agencies = agencies;
}
);
}
createAgent() {
this.agentService.addAgent(this.model).subscribe(() => {
this._location.back();
})
}
}
And lastly, this is the HTML:
<form (ngSubmit)="createAgent()" autocomplete="off">
<input
name="firstName"
[(ngModel)]="model.firstName"
class="form-control mt-3"
type="text"
placeholder="First name"
>
<input
name="lastName"
[(ngModel)]="model.lastName"
class="form-control mt-3"
type="text"
placeholder="Last name"
>
<input
name="email"
[(ngModel)]="model.email"
class="form-control mt-3"
type="text"
placeholder="E-mail"
>
<input
name="phone"
[(ngModel)]="model.phone"
class="form-control mt-3"
type="text"
placeholder="Phone"
>
<select name="agency" [(ngModel)]="model.agency" >
<option *ngFor="let agency of agencies" [ngValue]="agency">{{ agency.id }}</option>
</select>
<button class="btn btn-success btn-sm mt-3" style="margin-right: 2%; box-shadow: 1px 1px grey;" type="submit">Add</button>
</form>
How can I pass the agency in a way that its id will be saved in the database? I've tried saving it as a text and making the given id match an existing agency. I've also tried retrieving the agencies from the db and passing them in a tag, but it still didn't work. What is the right way to do this?