fix(useLazyQuery): load() on server, fix #1495

This commit is contained in:
Guillaume Chau
2024-01-24 10:12:02 +01:00
parent 460a0dbd11
commit 330564c7f4
4 changed files with 49 additions and 13 deletions
@@ -1,7 +1,7 @@
<script lang="ts">
import gql from 'graphql-tag'
import { useLazyQuery } from '@vue/apollo-composable'
import { defineComponent, computed, reactive } from 'vue'
import { defineComponent, computed } from 'vue'
export default defineComponent({
setup () {
@@ -12,6 +12,7 @@ export default defineComponent({
label
messages {
id
text
}
}
}
@@ -44,6 +45,10 @@ export default defineComponent({
<div v-if="channel">
<div>Loaded channel: {{ channel.label }}</div>
<div>Messages: {{ channel.messages.length }}</div>
<div v-for="message in channel.messages" :key="message.id" class="message">
{{ message.text }}
</div>
</div>
</div>
</template>
@@ -35,4 +35,9 @@ describe('Vue 3 + Apollo Composable', () => {
cy.get('.message').should('have.lengthOf', 1)
cy.contains('.message', 'Hello world!')
})
it('loads lazy query with load call', () => {
cy.visit('/lazy-query-immediately')
cy.contains('.message', 'Meow!')
})
})
@@ -2,8 +2,16 @@ import { DocumentNode } from 'graphql'
import { isRef } from 'vue-demi'
import { useQueryImpl, DocumentParameter, VariablesParameter, OptionsParameter, UseQueryOptions, UseQueryReturn } from './useQuery'
import type { OperationVariables } from '@apollo/client/core'
import { isServer } from './util/env.js'
export interface UseLazyQueryReturn<TResult, TVariables extends OperationVariables> extends UseQueryReturn<TResult, TVariables> {
/**
* Activate the query and starts loading.
* @param document Override document
* @param variables Override variables
* @param options Override options
* @returns Returns false if the query is already active, otherwise the next result of the query.
*/
load: (document?: DocumentNode | null, variables?: TVariables | null, options?: UseQueryOptions | null) => false | Promise<TResult>
}
@@ -35,6 +43,11 @@ export function useLazyQuery<
if (isFirstRun) {
query.forceDisabled.value = false
// If SSR, we need to start the query manually since `watch` on `isEnabled` in `useQueryImpl` won't be called.
if (isServer) {
query.start()
}
return new Promise<TResult>((resolve, reject) => {
const { off: offResult } = query.onResult((result) => {
if (!result.loading) {
+25 -12
View File
@@ -251,6 +251,13 @@ export function useQueryImpl<
return
}
// On server the watchers on document, variables and options are not triggered
if (isServer) {
applyDocument(documentRef.value)
applyVariables(variablesRef.value)
applyOptions(unref(optionsRef))
}
started = true
error.value = null
loading.value = true
@@ -465,7 +472,12 @@ export function useQueryImpl<
const isEnabled = computed(() => enabledOption.value && !forceDisabled.value && !!documentRef.value)
// Applying options first (in case it disables the query)
watch(() => unref(optionsRef), value => {
watch(() => unref(optionsRef), applyOptions, {
deep: true,
immediate: true,
})
function applyOptions (value: UseQueryOptions<TResult, TVariables>) {
if (currentOptions.value && (
currentOptions.value.throttle !== value.throttle ||
currentOptions.value.debounce !== value.debounce
@@ -474,16 +486,15 @@ export function useQueryImpl<
}
currentOptions.value = value
restart()
}, {
deep: true,
immediate: true,
})
}
// Applying document
watch(documentRef, value => {
watch(documentRef, applyDocument)
function applyDocument (value: DocumentNode | null | undefined) {
currentDocument = value
restart()
})
}
// Applying variables
let currentVariables: TVariables | undefined
@@ -494,17 +505,19 @@ export function useQueryImpl<
} else {
return undefined
}
}, (value) => {
}, applyVariables, {
deep: true,
immediate: true,
})
function applyVariables (value?: TVariables) {
const serialized = JSON.stringify([value, isEnabled.value])
if (serialized !== currentVariablesSerialized) {
currentVariables = value
restart()
}
currentVariablesSerialized = serialized
}, {
deep: true,
immediate: true,
})
}
// Refetch