orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
3.21k stars 337 forks source link

Hooks queryOptions overwrite must include queryKey #1563

Open DragosRomaniuc opened 3 months ago

DragosRomaniuc commented 3 months ago

What are the steps to reproduce this issue?

  1. Generate a query
  2. Use the query and try to add extra queryOptions
    const {
    data: orderSummary,
    isLoading: orderIsLoading,
    isSuccess: orderIsSuccess,
    refetch: artistsRefetch,
    } = useGetOrderSummaryForUser(id as string, {
    query: {
      queryKey: getGetOrderSummaryForUserQueryKey(id as string),
      enabled: true, <-- this one
    },
    });
  3. enabled: true cant be added alone without queryKey: getGetOrderSummaryForUserQueryKey(id as string) because it will complain that queryKey Property 'queryKey' is missing in type '{ enabled: true; }' but required in type 'UseQueryOptions

What happens?

Hooks queryOptions can't be overwritten without applying the queryKey as well because queryKey is not optional.

Screenshot 2024-08-06 at 16 49 38 Screenshot 2024-08-06 at 16 49 53

What were you expecting to happen?

I want to be able to overwrite the queryOptions without the need to include the queryKey.

Screenshot 2024-08-06 at 16 50 06

Any logs, error output, etc?

Any other comments?

What versions are you using?

System: OS: macOS 14.5 CPU: (10) arm64 Apple M1 Max Memory: 925.28 MB / 32.00 GB Shell: 5.9 - /bin/zsh npmPackages: orval: ^7.0.1 => 7.0.1

Please execute npx envinfo --system --npmPackages orval,zod,axios,msw,@tanstack/react-query and paste the results here.

ipko1996 commented 2 months ago

Oh boy!

Digging through the docs, found this:

   const query = useQuery<AsyncReturnType<typeof queryFn>, TError, TData>(
     queryKey,
     queryFn,
     { enabled: !!petId, ...queryOptions },
   );

This is generated code, so you don't need to manually (or painfully) stitch that into the query yourself! No hacks needed.

🥁🥁🥁

The solution!

If you look closely in the example:

  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path <-------------
          required: true
          description: The ID of the pet to retrieve
          schema:
            type: string

PATH!!! So when you work with your OpenAPI schema, make sure you do it this way.

In my case, since I'm using @hono/zod-openapi, this was the solution:

export const getPetRoute = createRoute({
  method: "get",
  path: "/pets/{petId}",
  tags: ["pets"],
  operationId: "Get pet by ID",
  request: {
    params: z.object({
      petId: z.string().min(3), // Must match with `path`
    }),
  },
  responses: {
    200: {
      description: "Returns the pet's breed and name",
      content: {
        "application/json": {
          schema: z.object({
            name: z.string(),
            breed: z.string(),
          }),
        },
      },
    },
  },
});

After this it will generate the query for you, and you can just use

  const { data, refetch } = useGetPetById(""); // This won't make a query when you load the page