Reputation: 411
I have to calculate the total number of business days between selected dates and I am using the following logic
this.businessDays = this.calcBusinessDays(this.startDate, this.endDate);
calcBusinessDays(d1: Date, d2: Date) {
let date1 = new Date(d1);
let date2 = new Date(d2);
let oneDay = 1000 * 60 * 60 * 24;
let difference = Math.floor((date2.getTime() - date1.getTime()) / oneDay);
let businessDays = 0;
let i: number;
this.httpService
.getHolidays(moment(date1).format('YYYY-MM-DD'), moment(date2).format('YYYY-MM-DD')) //start-date and end date are a part of query params in YYYY-MM-DD format.
.subscribe((res: HttpResponse<HolidaysListInterface>) => {
this.holidaysList = res.body.holidayDates;
for (i = 0; i < difference; ++i) {
let day = date1.getDay();
let isHoliday = this.holidaysList.indexOf(moment(date1).format('YYYY-MM-DD')) != -1;
if (day != 0 && day != 6 && !isHoliday) {
++businessDays;
}
date1.setDate(date1.getDate() + 1);
}
});
return businessDays;
}
Now the problem here is I am getting 0
every time as a return value. The function is returning the value even before the Http call is finished. What's the workaround for this?
Upvotes: 1
Views: 667
Reputation: 31125
Because that is how asynchronous requests work. They are executed asynchronously disregarding the actual order of execution you specify. You could learn more about it here.
One line solution to your problem is
anything that directly depend on the response from the HTTP call should be inside the subscription
or in other words
subscribe where it's response is required
One more thing to remember is you cannot return an async variable (businessDays
here) synchronously.
Also you could use RxJS map
operator to transform the response to your required format
Try the following
businessDays: any;
someFunc() {
this.calcBusinessDays(this.startDate, this.endDate).subscribe(
businessDays => this.businessDays = businessDays,
error => {
// always good practice to handle HTTP errors
}
);
}
calcBusinessDays(d1: Date, d2: Date): Observable<any> { // <-- return observable here
let date1 = new Date(d1);
let date2 = new Date(d2);
let oneDay = 1000 * 60 * 60 * 24;
let difference = Math.floor((date2.getTime() - date1.getTime()) / oneDay);
let businessDays = 0;
let i: number;
return this.httpService
.getHolidays(moment(date1).format('YYYY-MM-DD'), moment(date2).format('YYYY-MM-DD')) //start-date and end date are a part of query params in YYYY-MM-DD format.
.pipe(
map((res: HttpResponse<HolidaysListInterface>) => {
this.holidaysList = res.body.holidayDates;
for (i = 0; i < difference; ++i) {
let day = date1.getDay();
let isHoliday = this.holidaysList.indexOf(moment(date1).format('YYYY-MM-DD')) != -1;
if (day != 0 && day != 6 && !isHoliday) {
++businessDays;
}
date1.setDate(date1.getDate() + 1);
}
return businessDays; // <-- return modified value here
})
);
}
Upvotes: 3