Serialization of Date?

Is there any suggested guidance on how to handle js/json serialization? I ran into an issue using the hono client where the types break due to a Date being typed as a string after being returned from a hono route I see there are no data transformers provided by hono, so wondering what suggestions there are. https://discord.com/channels/1011308539819597844/1248521918554963979
14 Replies
Aditya Mathur
Aditya Mathur7mo ago
Yes, this is something you will have to manually do because in that way the implementation remains simple and fast. For example if you have created_on and updated_on where you want to do this transformation, stick to manual. Just add another then after the request and process the output. But if you have a more complex use case you can use something like superjson - https://github.com/blitz-js/superjson
GitHub
GitHub - blitz-js/superjson: Safely serialize JavaScript expression...
Safely serialize JavaScript expressions to a superset of JSON, which includes Dates, BigInts, and more. - blitz-js/superjson
DiamondDragon
DiamondDragonOP7mo ago
Ok - all my tables have a created/updated on field. One thing I’m trying to grok is I’m using drizzle queries which are returning nested arrays of different table data so will have think more on that
Aditya Mathur
Aditya Mathur7mo ago
I would suggest creating a function which can serialise and deserialise this. Adding a lib can bloat things up Hey! If you don't have further questions on this, can you mark it as resolved. Thank You
DiamondDragon
DiamondDragonOP5mo ago
Still not solved, can you provide a working code sample? https://zenn.dev/kosei28/articles/hono-superjson for example I tried to implement this but most of the types used in this hcs proxy are not exported from hono today it seems? So the modified hcs client is not typesafe, or at least my attempt
DiamondDragon
DiamondDragonOP5mo ago
Hi, do you have any code samples on this? Basically, my code is looking ugly like this in order to handle typing the date strings back to Date 😦
const res = await apiClient.auth['auth-state'][':workOsUserId'].$get({
param: { workOsUserId },
})
if (!res.ok) {
throw new Error(`Error fetching auth state: ${res.status}`)
}
const data = await res.json()

if (data.user) {
return {
user: data.user
? {
...data.user,
createdAt: new Date(data.user.createdAt),
updatedAt: data.user.updatedAt ? new Date(data.user.updatedAt) : null,
}
: null,
organizations: data.organizations.map((org) => ({
...org,
createdAt: new Date(org.createdAt),
updatedAt: org.updatedAt ? new Date(org.updatedAt) : null,
})),
workspaces: data.workspaces.map((workspace) => ({
...workspace,
createdAt: new Date(workspace.createdAt),
updatedAt: workspace.updatedAt ? new Date(workspace.updatedAt) : null,
})),
}
}
return {
user: null,
organizations: [],
workspaces: [],
}
},
const res = await apiClient.auth['auth-state'][':workOsUserId'].$get({
param: { workOsUserId },
})
if (!res.ok) {
throw new Error(`Error fetching auth state: ${res.status}`)
}
const data = await res.json()

if (data.user) {
return {
user: data.user
? {
...data.user,
createdAt: new Date(data.user.createdAt),
updatedAt: data.user.updatedAt ? new Date(data.user.updatedAt) : null,
}
: null,
organizations: data.organizations.map((org) => ({
...org,
createdAt: new Date(org.createdAt),
updatedAt: org.updatedAt ? new Date(org.updatedAt) : null,
})),
workspaces: data.workspaces.map((workspace) => ({
...workspace,
createdAt: new Date(workspace.createdAt),
updatedAt: workspace.updatedAt ? new Date(workspace.updatedAt) : null,
})),
}
}
return {
user: null,
organizations: [],
workspaces: [],
}
},
Aditya Mathur
Aditya Mathur5mo ago
Can you share a sample reproduction? It will be easier for me to look into it If this is something which you are doing for a single route handler then you can create a function which checks if the value is present then return the date or return null. Something like this
function refineDate(value?: string) {
if (value) return new Date(value)
return null
}
function refineDate(value?: string) {
if (value) return new Date(value)
return null
}
Or if you doing this across your codebase you can use lodash, you can use the cloneDeepWith function to create a custom parse which checks if the key is createdAt or updatedAt then update the value exactly how we are doing it in the refineDate function.
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
ambergristle
ambergristle4w ago
hey @DiamondDragon! have you considered parsing with zod client-side?
DiamondDragon
DiamondDragonOP4w ago
yeah that's a good suggestion. i saw someone else mention that trick
ambergristle
ambergristle4w ago
if you're already using drizzle, it's an easy extension to make if you only need it to coerce these dates, and you know it's only going to be a few fields, there's a good argument to be made for deserializing on your own. but then you have to ask whether that's something you care to spend time on 🤷
DiamondDragon
DiamondDragonOP4w ago
deserializing just sounds like something that has prob been solved a million times, so i guess you'd think itd be handled naturally by the lib. but all good i guess. @ambergristle
ambergristle
ambergristle4w ago
no problem! it's actually a somewhat complicated challenge when the client sees an iso date, there's no way for it to know by default whether that's meant to be coerced or not you could try to integrate with a validator, but client-side logic isn't as standardized as backends are, so i'd expect that to be a controversial solution i expect it would also be pretty tough to incorporate into the type system in practice, i think you see a lot of
const res = await client.users.$get();
return res.json().map((userResponse) => new User(userResponse));
const res = await client.users.$get();
return res.json().map((userResponse) => new User(userResponse));
it might be implemented with zod or another validator, or a class, or a function, or whatever really but arguably making requests + processing responses are separate concerns
DiamondDragon
DiamondDragonOP4w ago
ah thanks for that explaination. yeah something i am not familiar with
ambergristle
ambergristle4w ago
no problem! happy to answer any other qs you might have

Did you find this page helpful?