T
tRPC

wrapper on useMutation (and another for useQuery) for creating multiple hooks

wrapper on useMutation (and another for useQuery) for creating multiple hooks

Mmlody_krol9/5/2023
hi i want to create a wrapper for my router, basically I would like to achive somethink like that This is my appRouter:
export const appRouter = router({
todoService: todoServiceRoutes,
})

export type AppRouter = typeof appRouter
export const appRouter = router({
todoService: todoServiceRoutes,
})

export type AppRouter = typeof appRouter
This is my todoService router:
export const todoServiceRoutes = router({
add: publicProcedure
.input(apiTodoSchemaValidator.insertTodoSchema)
.mutation(async ({ input: { title, description, isDone } }) => {
return db
.insert(todos)
.values({
title,
description,
isDone,
})
.returning({ insertedId: todos.id })
}),
getAll: publicProcedure.query(async () => {
return db.select().from(todos).orderBy(desc(todos.id))
})
})
export const todoServiceRoutes = router({
add: publicProcedure
.input(apiTodoSchemaValidator.insertTodoSchema)
.mutation(async ({ input: { title, description, isDone } }) => {
return db
.insert(todos)
.values({
title,
description,
isDone,
})
.returning({ insertedId: todos.id })
}),
getAll: publicProcedure.query(async () => {
return db.select().from(todos).orderBy(desc(todos.id))
})
})
This is my wannabe custom hook:
export function useCustomMutation<T extends AppRouter>(
config: ProcedureConfig<T>
) {
const utils = api.useContext()

const { service, action, optimisticUpdateEndpoint } = config

return api[service][action].useMutation({
onMutate: async input => {
await utils[service][optimisticUpdateEndpoint].cancel()
const updatedResults = utils[service][optimisticUpdateEndpoint].getData()

const optimisticUpdate = updatedResults && [
{ ...input, id: updatedResults.length + 1 },
...updatedResults,
]

utils[service][optimisticUpdateEndpoint].setData(
undefined,
optimisticUpdate
)
},
onError: () => {
utils[service][optimisticUpdateEndpoint].invalidate()
},
onSuccess: () => {
utils[service][optimisticUpdateEndpoint].invalidate()
},
})
}
export function useCustomMutation<T extends AppRouter>(
config: ProcedureConfig<T>
) {
const utils = api.useContext()

const { service, action, optimisticUpdateEndpoint } = config

return api[service][action].useMutation({
onMutate: async input => {
await utils[service][optimisticUpdateEndpoint].cancel()
const updatedResults = utils[service][optimisticUpdateEndpoint].getData()

const optimisticUpdate = updatedResults && [
{ ...input, id: updatedResults.length + 1 },
...updatedResults,
]

utils[service][optimisticUpdateEndpoint].setData(
undefined,
optimisticUpdate
)
},
onError: () => {
utils[service][optimisticUpdateEndpoint].invalidate()
},
onSuccess: () => {
utils[service][optimisticUpdateEndpoint].invalidate()
},
})
}
and thats how I want to use it:
export function useAddTodo() {
const { mutation, isLoading } = useCustomMutation({
service: 'todoService',
action: 'add',
optimisticUpdateEndpoint: 'getAll',
})
export function useAddTodo() {
const { mutation, isLoading } = useCustomMutation({
service: 'todoService',
action: 'add',
optimisticUpdateEndpoint: 'getAll',
})
now how I can make it typesafe with intellisense (code completition, etc)

Looking for more? Join the community!

T
tRPC

wrapper on useMutation (and another for useQuery) for creating multiple hooks

Join Server