MarM
tRPCβ€’3y ago
Mar

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

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

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))
  })
})


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()
    },
  })
}


and thats how I want to use it:

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)
Was this page helpful?