Во-первых, вы должны попытаться поговорить с людьми, ответственными за API - принимать даты в виде строк вместо объектов даты - это, по меньшей мере, плохая практика.
Если это невозможно, я бы сказал, Лучше всего конвертировать его как можно позже, чтобы не хоронить эту ужасную логику c в логи ваших компонентов / услуг c. Используйте HttpInterceptor для преобразования всех данных в ваших исходящих запросах. Это решение будет хорошо, если вы хотите обрабатывать его глобально для каждого исходящего запроса. Пример перехватчика (не тестировался - выписан из моей головы) ниже:
@Injectable({
providedIn: 'root'
})
export class DateInterceptor implements HttpInterceptor {
constructor() { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
body: this.dateToString(request.body)
});
return next.handle(request);
}
dateToString(object: any): string {
if (object === null || object === undefined) {
return object;
}
if (typeof object !== 'object') {
return object;
}
for (const key of Object.keys(object)) {
const value = object[key];
if (value instanceof Date) {
object[key] = this.formatDate(value);
} else if (typeof value === 'object') {
this.dateToString(value);
}
}
}
formatDate(date: Date): string {
return date.toISOString();
}
} this.dateToString(value);
}
}
}
formatDate(date: Date): string {
return date.toISOString();
}
Это также необходимо зарегистрировать в вашем модуле - см. Связанные документы.
Я думаю, что рекурсивное преобразование тела запроса, хотя и не идеальное с точки зрения производительности, является вполне приемлемым решением, пока они не исправят свой API.
Если вы используете более одного API, вы можете выполнить проверку, если запрос относится к этому конкретному API, например проверяя URL-адрес запроса:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (request.url.toLocaleLowerCase().includes('some-terrible-api')) {
request = request.clone({
body: this.dateToString(request.body)
});
}
return next.handle(request);
}
Конечно, если вы используете других провайдеров дат (например, момент), вам необходимо соответствующим образом изменить свой код, но идея остается прежней.