-
-
Notifications
You must be signed in to change notification settings - Fork 471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to handle dependent queries? #1941
Comments
Hi, I think the best thing I can do is redirect you to the documentation https://openapi-ts.pages.dev/openapi-react-query/ But for a quick example, you can either use: const { data } = $query.useQuery('get', '/users', {}, { placeholder: keepPreviousData, enabled: true })
const { data } = useQuery($query.queryOptions('get', '/users', {}, { placeholder: keepPreviousData, enabled: true })) Both allow you to use query options properly. |
Well, maybe I did not point out the problem precisely, but it is not related to being able to pass the proper parameters to the query engine. The generated code from e.g. an endpoint specification might contain non optional values. Even if we can pass the Given an endpoint with the signature Of course one fix could be to just specify everything optional in the schema but this is not only wrong API design but also requires much much more coding overhead. Is my example understandable? |
Required parameters must always be defined. For example: const { data } = $query.useQuery('get', '/users/:id', {}) // Typescript shouting
const { data } = $query.useQuery('get', '/users/:id', { params: { path: { id: 4 } } }}) // All good And it will work the same with body parameters, query params, etc. Thanks to openapi-fetch and openapi-typescript. |
Yeah exactly thats the problem in combination with the Given the need of a dependent query you can only trick the compiler into a valid statement. Let me show you a quick example: // Initial query, might be anything else which can be pending
const { data: users } = $query.useQuery('get', '/users', {});
// Find a property where any follow-up query depends on
const id = (users || [] ).find(u => u.cool)?.id;
// Disable the query unless the property is there
// ISSUE: Must trick compiler with "id!" to keep it clean!!
const { data } = $query.useQuery('get', '/users/:id', { params: { path: { id: id! } } }, { enabled: !!id }) For further understanding of the need for a feature/enhancement for this have a read at e.g. https://tkdodo.eu/blog/react-query-and-type-script#type-safety-with-the-enabled-option More understandable now? I just want to suggest a way to bake in type safety into the package, so that parameters which are relevant for a query which is not enabled, might be optional. EDIT: function dependOn<T, R>(
dependency: T | undefined,
queryFn: (dependency: T) => Promise<R>,
): () => Promise<R> {
return typeof dependency === "undefined"
? () => Promise.reject(new Error("Dependency not passed to query function"))
: () => queryFn(dependency);
} |
Okay now I actually understand your point. In fact I actually encountered that multiple time. And I actually used The goal of openapi-typescript and openapi-fetch is to give type-safety, not runtime safety. This is why it is so lightweight, because it primarily bases everything on types. Meaning we can't know at runtime if something is required or not. Your proposed solution is interesting but I don't see how we could use that internally as we don't have the information about required or mandatory types. We could expose a similar function for that: $query.useQuery(
"get",
"/users/:id",
...dependsOn([id, filter], ([id, filter]) => ({
params: { path: { id }, query: { filter } },
}))
); The first parameter is a list of And this should return: $query.useQuery(
"get",
"/users/:id",
{ params: { path: { id }, query: { filter } } },
{ enabled: id && filter }
); What do you think? |
Some ideas:
const SKIP = {queryKey: [] as any, queryFn: skipToken} as const;
useQuery(id ? $query.queryOptions(...) : SKIP); |
I like the idea. As long as we can keep the correct type inference of the returned object it is fine. Also I think this should just be an overloaded signature as there are still lot of query cases which are not dependent. In fact the |
We are already using the openapi-fetch package to generate our client code for the specification.
We want to establish the usage of react query too, so we're glad that you work on a component here.
Basically we have a very granular backend API which results in a lot of dependent query calls.
How is this handled in your query package? Usually the query options are mixed with additional flags, in this case I am aware of
enabled
andskipToken
. But as the specification might contain mandatory parameters, it can't just work out.Any feedback on this?
The text was updated successfully, but these errors were encountered: