I just discovered the afterQuery lifecycle hook in the docs and got interested. The doc section currently is as brief as brief can get, but maybe we can gather some intelligence here that could be used to add to the docs.
Two questions arose for me:
- “Use it to sanitize data” it says. I was wondering what the code pattern would be there, b/c the data object passed to that function is completely immutable, also any fields contained in it. Maybe it’s specific to my use case, but i always get “object is not extensible” or “Cannot assign to read only property” errors, so the only option i saw fit was to clone it, modify the clone and return that instead.
I would assume that sealing the object is not a thing that redwood does on purpose, but rather Apollo. But then again it doesn’t make sense why it’s allowed to edit the query object retrieved fromcache.readQuery
, but not the default query object the cell uses. So is it true the only way is to act on a clone? Maybe somebody could provide a nice SFW example that we could eventually add to the documentation. - I got interested in this hook because i have a lot of function calls rendering custom display values in my components (they consume the query and render a nice chakra UI accordion list from it) that (a.) were not very DRY and (b.) were needlessly executed over and over again on each interaction due to react renders … so i was wondering if there was a way to pre-render those “display fields” before i pass them to the components. Effectively i am now using
afterQuery
to add additional fields to the resultset and have extended the query type to refer to from my components. I had a quick thought about adding these fields to the service in the api, but (a): they are not part of the model, they are just “virtual” for display/frontend rendering purposes only and (b): they rely on the l10n setting of the user’s browser, so this being done the web side seems the natural spot. So, what do you think: is adding additional “for display purposes only” fields, thus generating a custom extended query type an acceptable usage of this hook – or am i going to hell for this and only not knowing it yet?
Click for a code
export type PrerenderedInterview = {
displayTime: string
shortDisplayDate: string
longDisplayDate: string
} & InterviewsQuery['interviews'][0]
// https://redwoodjs.com/docs/cells#afterquery
export const afterQuery = (data: CellSuccessProps<InterviewsQuery>) => {
const newData = { ...data }
newData.interviews = data.interviews.map((record) => {
return {
...record,
shortDisplayDate: date.getShortDisplayDate(record.startAt),
longDisplayDate: date.getLongDisplayDate(record.startAt),
displayTime:
date.getDisplayTime(record.startAt) +
(record.startAt &&
record.endAt &&
' – ' + date.getDisplayTime(record.endAt)),
}
})
return newData
}