-
-
Notifications
You must be signed in to change notification settings - Fork 324
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
Vue query improve reactive support #852
Conversation
Someone is attempting to deploy a commit to a Personal Account owned by @anymaniax on Vercel. @anymaniax first needs to authorize it. |
@anymaniax - Now ready for review, remaining type fixes added. Thank you for your consideration. |
This seems to work quite well for me |
I see that the tests are not passing. There is a problem for |
@anymaniax - Are you available on a chat anywhere? Or can you share the output of failure here? I can take a look then! Many Thanks |
I try to be available on the Orval discord if you need to talk to me. You will see the problem if in the project you run the tests in the tests folder you just need to install the dependencies in it and then |
packages/query/src/index.ts
Outdated
props.filter((prop) => prop.type !== GetterPropType.HEADER), | ||
'implementation', | ||
); | ||
|
||
if (OutputClient.VUE_QUERY) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anymaniax isOutputClient.VUE_QUERY
a reliable way to detect if the runner is vue only?
Ta
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it's the only way to know it
All good I see this now! Left a comment above. Will join discord. Ta |
As I've demonstrated in #851 (comment) the query isn't being refetched when selected petId changes. import { watch } from 'vue';
watch(petId, () => {
petQuery.refetch();
}); |
I think I figured it out. export const getShowPetByIdQueryKey = (petId: MaybeRef<string>, version = 1) =>
- [`/v${unref(version)}/pets/${unref(petId)}`] as const;
+ [`/v`, version, `/pets/`, petId] as const; |
Thanks @Maxim-Mazurok I agree with the query key solution as Vue-query handles it and unwraps automatically. Let me take a look when I get some time. My first suggestion was to update queryKey also. Cheers |
This seems to fix that: diff --git a/packages/query/src/index.ts b/packages/query/src/index.ts
index 4f62c9a..e126713 100644
--- a/packages/query/src/index.ts
+++ b/packages/query/src/index.ts
@@ -402,10 +402,11 @@ const generateQueryRequestFunction = (
hasSignal,
});
- return `export const ${operationName} = (\n ${toObjectString(
- props,
- 'implementation',
- )} ${optionsArgs} ): Promise<AxiosResponse<${
+ const queryProps = isVue(outputClient)
+ ? vueWrapTypeWithMaybeRef(toObjectString(props, 'implementation'))
+ : toObjectString(props, 'implementation');
+
+ return `export const ${operationName} = (\n ${queryProps} ${optionsArgs} ): Promise<AxiosResponse<${
response.definition.success || 'unknown'
}>> => {${bodyForm}
return axios${ |
Found another option which also works: export const getShowPetByIdQueryKey = (petId: MaybeRef<string>, version = 1) =>
computed(() => [`/v${unref(version)}/pets/${unref(petId)}`]); |
Implemented following option based on this PR [`/v`, version, `/pets`] |
@anymaniax tests are now passing for this, so awaiting your review. |
I did it this way because I wasn't sure how Vue Query hashes the key, I thought that if it does Checking out their code, I've created a test to confirm that we can drop function isPlainObject(o) {
if (!hasObjectPrototype(o)) {
return false
}
// If has modified constructor
const ctor = o.constructor
if (typeof ctor === 'undefined') {
return true
}
// If has modified prototype
const prot = ctor.prototype
if (!hasObjectPrototype(prot)) {
return false
}
// If constructor does not have an Object-specific method
if (!prot.hasOwnProperty('isPrototypeOf')) {
return false
}
// Most likely a plain Object
return true
}
function hasObjectPrototype(o) {
return Object.prototype.toString.call(o) === '[object Object]'
}
function hashQueryKey(queryKey) {
return JSON.stringify(queryKey, (_, val) =>
isPlainObject(val)
? Object.keys(val)
.sort()
.reduce((result, key) => {
result[key] = val[key]
return result
}, {})
: val,
)
}
console.log(hashQueryKey(["v", 1, "air", "plane"])) // prints ["v",1,"air","plane"]
console.log(hashQueryKey(["v", 1, "airplane"])) // prints ["v",1,"airplane"] |
Just tested this on my project and it generates everything well and works well, so LGTM. There's another reactivity issue tho, now with Basically, we have this now: I've solved it by doing this: - return { queryKey, queryFn, enabled: !!myArgument, ...queryOptions };
+ return { queryKey, queryFn, enabled: computed(() => !!unref(myArgument)), ...queryOptions }; Seems to work fine. I'll submit PR |
@@ -49,7 +49,7 @@ export const listPets = ( | |||
export const getListPetsQueryKey = ( | |||
params?: MaybeRef<ListPetsParams>, | |||
version = 1, | |||
) => [`/v`, version, `/pets`, ...(params ? [params] : [])] as const; | |||
) => ['v', version, 'pets', ...(params ? [params] : [])] as const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RE: I did it this way because I wasn't sure how Vue Query hashes the key, I thought that if it does [].join("") for example - then /v1/air/plane would have the same key as /v1/airplane which would be a mistake.
I've changed what functionality you had here previously. Is this what you're describing as a requirement? (forward slash removed). Any string concatenation with variables even in the pathname should be cut up and recognised as a var.
eg: /something${var}/pets/${petId}
will explode to ['something',var,'pets',petId]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's all good now, thank you. I was just confirming that we can get rid of slashes and keep arrays just like you did, all good currently 👍
vue-query supports ref here I'm pretty sure, So this only needs to be changed to: |
packages/query/src/index.ts
Outdated
@@ -849,7 +878,7 @@ export const ${camel( | |||
`${operationPrefix}-${type}`, | |||
)}(${queryOptionsVarName}) as ${returnType}; | |||
|
|||
query.queryKey = ${queryOptionsVarName}.queryKey; | |||
query.queryKey = ${queryOptionsVarName}.queryKey as QueryKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to apply to samples/react-query/hook-mutator/endpoints.ts
as well as vue one, not sure if that was your intention.
It doesn't seem to be the case...
Nope, that doesn't work, it's being evaluated to
I guess I could... But I rather patch it up in the generator, see gkweb#2 We don't have to include it in this PR tho if you'd like to do it separately. Seems like a small fix to me tho. |
Hello guys, thanks for the work can I do something here? is the pull request ready? |
Hey @anymaniax - yeah any subsequent issue can be fixed in additional pull requests. |
Just did a first tour. Insane work thanks guys ❤️ |
import { useShowPetById } from '../api/endpoints/petstoreFromFileSpecWithTransformer'; | ||
|
||
const props = defineProps<{ petId: string }>(); | ||
const petId = computed(() => props.petId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the computed is not really need here right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The props is a reactive object. Wrapping in the computed can help to demonstrate reactivity of the individual prop though?
https://vuejs.org/guide/extras/reactivity-transform.html#reactive-props-destructure
Let me know if you want this changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no it was to be sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks 🎉
Great work, any idea when you will release this to NPM? |
This week. I want to add one more pull request before the release. |
Changed my mind it's released right now |
* fix: correct `jsStringEscape` import * feat(namedParameters): add global `useNamedParameters` option * feat(namedParameters): add NAMED_PATH_PARAMS prop type * test(axios): add named parameters test * test(angular): add named parameters test * test(react-query): add named parameters test * fix(query): introduce destructured usage * test(svelte-query): add named parameters test * test(vue-query): add named parameters test * fix(vue-query): rework MaybeRef logic * fix(swr): introduce destructured usage * test(swr): add named parameters test * chore(cra): update react-scripts * fix(angular-app): update sample * fix(react-app): update sample * fix(react-app-with-swr): update sample * fix(react-query/basic-app): update sample * fix(react-query/custom-client-app): update sample * fix(react-query/form-data-app): update sample * fix(react-query/form-data-mutator-app): update sample * fix(react-query/form-url-encoded-mutator-app): update sample * fix(react-query/hook-mutator-app): update sample * fix(svelte-query): update sample * fix(vue-query-app): update sample * fix(namedParameters): optional arg when all params are optional
Status
READY/WIP/HOLD
READY
Description
Addresses: #851
A few sentences describing the overall goals of the pull request's commits.
Improves vue reactivity support.
Related PRs
List related PRs against other branches:
Todos
Steps to Test or Reproduce
Outline the steps to test or reproduce the PR here.
See the sample update, I've expanded on the sample by dynamically updating the list to load in a single pet.