Issue
I have a REST API that gives data in the following format:-
{"id": 1, "name": "New event", "date": "2020-11-14T18:02:00"}
And an interface in my frontend React app like this:-
export interface MyEvent {
id: number;
name: string;
date: Date;
}
I use axios to fetch response from the API.
const response = await axios.get<MyEvent>("/event/1");
const data = response.data;
However, data.date
remains a string due to typescript limitations.
This can cause problems later in the code, where I expect all such date fields to be an actual Date object.
I could probably do something like: data.date = new Date(data.date);
. But that won't be feasible approach for a lot of reasons.
Is there a better way of handling dates in typescript? How do you handle dates coming from API in response in general?
Solution
Update
Now that Zod has the coerce
option, I think it is a better approach to use it to validate & parse your incoming API response.
You can use it like this:-
const eventSchema = z.object({
number: z.number(),
name: z.string(),
date: z.coerce.date()
});
const myEvent = eventSchema.parse(response.data);
You can also create a type out of the eventSchema
to use it across your codebase:-
type MyEvent = z.infer<typeof eventSchema>
Old Solution
So the solution that best fits my use case is similar to the one mentioned by @Amy in the original question's comment.
So I use Axios interceptors to convert dates to a Date object.
const client = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL });
client.interceptors.response.use(originalResponse => {
handleDates(originalResponse.data);
return originalResponse;
});
export default client;
For identifying dates, I've used a regex expression, and for conversion to Date object, I've date-fns package.
const isoDateFormat = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d*)?$/;
function isIsoDateString(value: any): boolean {
return value && typeof value === "string" && isoDateFormat.test(value);
}
export function handleDates(body: any) {
if (body === null || body === undefined || typeof body !== "object")
return body;
for (const key of Object.keys(body)) {
const value = body[key];
if (isIsoDateString(value)) body[key] = parseISO(value);
else if (typeof value === "object") handleDates(value);
}
}
Answered By - Babri
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.