I’m stuck with a work-related task where I’m fetching data from the db and then send the data to an external api through post request. Right now I’m succesfully getting the data and processed it but the external api request gets through before the promise is resolved.
So I have this service class called EmployeeService, where I am getting some data from the db and processing it. To make it more readable I separated each steps in separate methods.
class EmployeeService {
constructor() {
this.employeeRepository = new EmployeeRepository();
}
getData(employeeId, department {
return {
name : 'John Doe',
attendance : this.getAttendanceHistory(employeeId, department)
};
}
async getAttendanceHistory(employeeId, department) {
if (department === 'accounts') {
return await this.#getAccountsDepartmentHistory(employeeId);
}
}
async #getAccountsDepartmentHistory(employeeId) {
const
cursor = await this.employeeRepository
.getHistory(
employeeId
),
messages = await cursor.toArray();
return messages.map((entry) => this.employeeService.processHistory(entry));
}
}
The above getData
method is being called from another service called EmployeeRecordsService
and then calls apiService with the data to send to an external endpoint.
class EmployeeRecordsService {
constructor() {
this.employeeService = new EmployeeService();
this.apiService = new ApiService();
}
sendData() {
const data = this.employeeService.getData('123', 'accounts');
const response = this.apiService.send(data);
return response;
}
}
class ApiService {
async send(data) {
console.log('final data: ', data)
return await this.request(
data
);
}
}
In EmployeeService, if I log the return value of getAccountsDepartmentHistory
, I get all the history and the promise is resolved. Same way, if I log the value of getAttendanceHistory
, the promise is resolved. However, if I log the return value of getData
it is either pending, or empty array or empty object. And also, final data
log gets called with no attendance data with empty object. I tried different ways to resolve the promise in getData
method like Promise.resolve, Promise.all and async/await, then final data
log shows Promise Pending.
How can I resolve the promise in EmployeeService instead of resolving in other services above? Why does each method in EmployeeService returns a promise even though I’m using await
?
Please note that I need to resolve the promise in EmployeeService before getting the data in EmployeeRecordsService. I’m trying to avoid making changes in other parts project cause a lot of things might break.
2
Answers
sendData
does nothing to wait on either promise. You need to actuallyawait
your calls togetData
andsend
, it’s not enough for those functions to be asynchronous down inside their implementations; callers all the way up the stack must also be asynchronous and mustawait
the promises being returned.Unfortunately when you have Promise / async actions, all your callers of an async function (In this case
getAttendanceHistory
is async) needs to handle those Promise. It doesn’t matter whether youawait
inside those functions already. A suggestion to fix your issue would be make sure toasync
andawait
them: