Skip to content

Commit d5f4124

Browse files
authored
Merge pull request #29 from guendev/fix/27
fix(core): support reactive GraphQL documents in useQuery
2 parents eadfe59 + 427257f commit d5f4124

File tree

4 files changed

+80
-11
lines changed

4 files changed

+80
-11
lines changed

.changeset/polite-crabs-obey.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@vue3-apollo/core": patch
3+
"@vue3-apollo/nuxt": patch
4+
---
5+
6+
fix(core): support reactive GraphQL documents in useQuery #27

packages/core/src/composables/useQuery.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export type UseQueryOptions<TData = unknown, TVariables extends OperationVariabl
119119
* @template TData - Type of the query result data
120120
* @template TVariables - Type of the query variables
121121
*
122-
* @param document - GraphQL query document or typed document node
122+
* @param document - GraphQL query document or typed document node (can be reactive ref or getter)
123123
* @param variables - Query variables (can be reactive ref or getter)
124124
* @param options - Query options including Apollo options and custom features
125125
*
@@ -139,7 +139,7 @@ export type UseQueryOptions<TData = unknown, TVariables extends OperationVariabl
139139
* ```
140140
*/
141141
export function useQuery<TData = unknown, TVariables extends OperationVariables = OperationVariables>(
142-
document: DocumentNode | TypedDocumentNode<TData, TVariables>,
142+
document: MaybeRefOrGetter<DocumentNode | TypedDocumentNode<TData, TVariables>>,
143143
variables?: MaybeRefOrGetter<TVariables>,
144144
options?: UseQueryOptions<TData, TVariables>
145145
) {
@@ -171,6 +171,8 @@ export function useQuery<TData = unknown, TVariables extends OperationVariables
171171
})
172172
}
173173

174+
const reactiveDocument = computed(() => toValue(document))
175+
174176
const getQueryOptions = () => {
175177
if (!options) {
176178
return {}
@@ -189,7 +191,7 @@ export function useQuery<TData = unknown, TVariables extends OperationVariables
189191
try {
190192
const queryResult = await client.query<TData, TVariables>({
191193
...getQueryOptions(),
192-
query: document,
194+
query: reactiveDocument.value,
193195
variables: toValue(reactiveVariables)
194196
})
195197

@@ -271,7 +273,7 @@ export function useQuery<TData = unknown, TVariables extends OperationVariables
271273
if (!isServer()) {
272274
try {
273275
const cachedData = client.readQuery<TData, TVariables>({
274-
query: document,
276+
query: reactiveDocument.value,
275277
variables: toValue(reactiveVariables)
276278
})
277279

@@ -288,7 +290,7 @@ export function useQuery<TData = unknown, TVariables extends OperationVariables
288290

289291
query.value = client.watchQuery<TData, TVariables>({
290292
notifyOnNetworkStatusChange: options?.notifyOnNetworkStatusChange ?? options?.keepPreviousResult,
291-
query: document,
293+
query: reactiveDocument.value,
292294
variables: toValue(reactiveVariables),
293295
...getQueryOptions()
294296
})
@@ -329,6 +331,13 @@ export function useQuery<TData = unknown, TVariables extends OperationVariables
329331
deep: true,
330332
flush: 'post'
331333
})
334+
335+
watch(reactiveDocument, () => {
336+
if (enabled.value) {
337+
stop()
338+
start()
339+
}
340+
})
332341
}
333342

334343
const refetch = async (variables?: TVariables) => {

packages/operations/src/entries/queries.graphql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ query Posts($userId: Int, $first: Int) {
1111
id
1212
...PostDetail
1313
}
14+
}
15+
16+
query Todos($userId: Int, $first: Int) {
17+
todos(userId: $userId, first: $first) {
18+
id
19+
}
1420
}

packages/web/src/App.vue

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
<script setup lang="ts">
2-
import type { PostsQueryVariables } from '@vue3-apollo/operations'
2+
import type {
3+
PostsQueryVariables,
4+
TodosQuery,
5+
TodosQueryVariables
6+
} from '@vue3-apollo/operations'
37
8+
import { gql } from '@apollo/client'
49
import { useFragment, useMutation, useQuery } from '@vue3-apollo/core'
510
import { PostDetailFragmentDoc, PostsDocument, UpdatePostDocument } from '@vue3-apollo/operations'
6-
import { reactive, ref } from 'vue'
11+
import { computed, reactive, ref } from 'vue'
712
813
const enabled = ref(true)
914
@@ -30,18 +35,36 @@ const { data } = useFragment({
3035
id: 1
3136
}
3237
})
38+
39+
const rawTodoQuery = ref(`
40+
query Todo($userId: Int, $first: Int) {
41+
todos(userId: $userId, first: $first) {
42+
id
43+
}
44+
}
45+
`)
46+
47+
const todoQuery = computed(() => gql(rawTodoQuery.value))
48+
49+
const { result: todosResult } = useQuery<TodosQuery, TodosQueryVariables>(todoQuery, vars, {
50+
keepPreviousResult: true
51+
})
3352
</script>
3453

3554
<template>
3655
<div class="min-h-screen bg-[#0b1220] text-gray-200 antialiased">
3756
<div class="max-w-5xl mx-auto p-6">
3857
<header class="mb-6">
3958
<h1 class="text-2xl font-semibold tracking-tight">
40-
Apollo Demo • Posts
59+
Apollo Demo
4160
</h1>
42-
<p class="text-sm text-gray-400 mt-1">
43-
Get posts by user ID and update title
44-
</p>
61+
<a
62+
target="_blank"
63+
href="https://graphqlplaceholder.vercel.app/graphql"
64+
class="text-sm text-gray-400 mt-1 hover:underline"
65+
>
66+
https://graphqlplaceholder.vercel.app/graphql
67+
</a>
4568
</header>
4669

4770
<section class="bg-slate-900/60 border border-white/10 rounded-xl shadow-lg backdrop-blur p-4 sm:p-6 space-y-4">
@@ -110,6 +133,31 @@ const { data } = useFragment({
110133
</div>
111134
</section>
112135

136+
<section class="bg-slate-900/60 border border-white/10 rounded-xl shadow-lg backdrop-blur p-4 sm:p-6 space-y-4 mt-10">
137+
<pre class="w-full overflow-auto text-sm leading-relaxed bg-slate-950/60 border border-white/10 rounded-lg p-3">
138+
type Todo {
139+
id: Int!
140+
title: String
141+
completed: Boolean
142+
}
143+
</pre>
144+
145+
<textarea
146+
v-model="rawTodoQuery"
147+
class="w-full px-3 py-2 rounded-lg bg-slate-800/70 text-gray-100 placeholder:text-gray-500 border border-slate-700 focus:(outline-none ring-2 ring-indigo-500)"
148+
rows="8"
149+
placeholder="Enter GraphQL query here"
150+
/>
151+
<div class="border-t border-white/10 pt-4 space-y-3">
152+
<div class="text-sm text-gray-300">
153+
Todos:
154+
</div>
155+
<pre class="w-full overflow-auto text-sm leading-relaxed bg-slate-950/60 border border-white/10 rounded-lg p-3">
156+
{{ todosResult?.todos }}
157+
</pre>
158+
</div>
159+
</section>
160+
113161
<footer class="mt-8 text-center text-xs text-gray-500">
114162
Powered by Vue 3 • Apollo • UnoCSS
115163
</footer>

0 commit comments

Comments
 (0)