Initially, explaining this with my actual code can be confusing, so I'll simplify the issue using a smaller example.
Imagine my project retrieves data from 2 tables on the server, employeeDetails and employeeNames.
employeeNames: This table consists of three columns - employeeNumber, firstName, and lastName. It contains a list of all employees with their unique employee number, first name, and last name.
employeeDetails: This table is where I perform httpGet and httpPost requests from my website. Let's say this table includes these fields:
- employee: Accepts the employee number as input
- qualifications: Allows users to input various qualifications as a string
- supervisor: Requires the supervisor's employee number, not the name
- manager: Needs the manager's employee number, not the name
While this setup exists in the backend, the frontend interface for employeeDetails includes additional members, making it more complex.
The Angular interface on the frontend appears as follows:
export interface employeeDetails
{
employee: number;
qualifications: string;
supervisor: number;
manager: number;
employeeName: string;
supervisorName: string;
managerName: string;
}
I use httpGet to fetch data from the backend API. After obtaining data from both tables, I have a function that populates the extra fields in the employeeDetails interface.
Controller
[HttpGet("[action]")]
public IActionResult getEmployeeNames()
{
using (var empApp= new EmployeeTable())
{
var empNames = new List<employeeNames>();
empNames = empApp.employeeNames.ToList();
return Json(empNames);
}
}
[HttpGet("[action]")]
public IActionResult employeeDetails()
{
using (var empApp= new EmployeeTable())
{
var empDetails = new List<employeeDetails>();
empDetails = empApp.employeeDetails.ToList();
return Json(empDetails);
}
}
Service
getEmployeeNames(): Observable<employeeNames[]> {
return this.http.get<employeeNames[]>(this.baseUrl + 'api/employeecontroller/getEmployeeNames')
.pipe(catchError(this.handleError('getItems', [])));
}
getEmployeeDetails(): Observable<employeeDetails[]> {
return this.http.get<employeeDetails[]>(this.baseUrl + 'api/employeecontroller/getEmployeeDetails')
.pipe(catchError(this.handleError('getItems', [])));
}
Component
getEmployeeInfo() {
this.employeeService.getEmployeeNames()
.subscribe(data => this.employeeNames = data);
this.employeeService.getEmployeeDetails()
.subscribe(data => this.employeeDetails = data);
fillEmployeeDetails();
}
fillEmployeeDetails() {
this.employeeDetails.forEach(elem => {
let emp = this.employeeNames.find(employee => {
return (employee.employeeNumber === elem.employeeNumber);
});
let sup = this.employeeNames.find(supervisor => {
return (supervisor.employeeNumber === elem.supervisor);
});
let man = this.employeeNames.find(manager=> {
return (manager.employeeNumber === elem.manager);
});
elem.employeeName = emp.firstName + " " + emp.lastName;
elem.supervisorName= sup.firstName + " " + sup.lastName;
elem.managerName= man.firstName + " " + man.lastName;
});
}
However, this function fails when called because it runs before the complete employeeNames table is fetched. Consequently, .find() returns null values for many employee numbers, leading to unexpected results.
MY INQUIRY
Should I consider using async/await and .toPromise() instead of subscribing to the service to await data fetching completion, or is there a better approach?
Any guidance or insights are highly appreciated. Thank you!