Вы должны вернуть Observable из вашей Службы, который не выдает никаких ошибок, чтобы вы могли напрямую использовать AsyncPipe в своем Компоненте для подписки (см. Также: Зачем обрабатывать ошибки с catchError, а не в обратном вызове ошибок подписки в Angular).
Преобразование вызовов Api, которые нельзя изменить, и возврат обещаний в Observables с помощью from
и использование операторов Rx JS с этого момента (я предполагаю this.wsseGenerator.getWSSEHeader()
это такой вызов).
Используйте switchMap
для сопоставления с другой наблюдаемой, pluck
или map
для извлечения / преобразования возвращаемых данных, catchError
для исправления ошибок и возврата наблюдаемой, которая не вызывает ошибок , finalize
делать что-то, когда ваши Наблюдаемые ошибки или завершены.
В вашем Сервисе:
import { Observable } from "rxjs";
import { switchMap, map, timeout, catchError, finalize } from "rxjs/operators";
getDayOverViewByGroupId(currentDate = null, groupId): Observable<any> {
return Observable.from(this.wsseGenerator.getWSSEHeader()).pipe( // use from to convert Promise to Observable
switchMap(header => {
header.append('Access-Control-Allow-Origin', '*');
header.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
let options = new RequestOptions({ headers: header });
let paramsData = {
groupId: groupId,
currentDate: currentDate
};
let params = that.serializeObject(paramsData);
// map to your http request
return this.http.post(`${that.baseUrl}/dayoverview?${params}`, null, options);
}),
map(this.getRelevantData), // get relevant data from http response
timeout(this.timeTimeout),
catchError(error => { // handle errors and return an Observable that doesn't error
console.log('Error occured in this.attendanceService.getDayOverViewByGroupId()', error);
if (error.name == 'TimeoutError') {
this.alert.present();
}
// you have to think about what default value you want to return on errors, null can be ok
return Observable.of(null);
}),
finalize(() => this.appFunctionCtrl.dismissLoader()) // do stuff on error and complete
);
}
private getRelevantData(response): any { // <-- don't return 'any' in your real code, create interfaces to type your data if you can
let dayOverViewByGroup = response.mobile_employee_dayoverview;
dayOverViewByGroup.forEach(element => {
// do your thing
}
console.log('dayOverViewByGroup', dayOverViewByGroup)
return dayOverViewByGroup;
}
В вашем Компоненте:
ngOnInit() {
this.dayOverViewByGroup$ = this.attendanceService.getDayOverViewByGroupId( .. ).pipe(
// If the Observable from your service can emit 'null' and you do
// map(days => days.map(..)) you will get an error
// so you might have to handle this case here
// 1. Option: filter out 'null' and 'undefined' values before your 'map' and don't emit anything
filter(Boolean)
// 2. Option: handle 'null' and 'undefined' in your map function
map(days => {
if (days) {
days.map( .. )
} else {
// do something else or don't do anything at all, i.e. remove the else case
}
})
)
}