feat: keepPreviousResult

This commit is contained in:
Guillaume Chau
2023-06-12 12:26:48 +02:00
parent 13bfbbea98
commit e794c1edde
6 changed files with 156 additions and 2 deletions
+2
View File
@@ -42,6 +42,8 @@
- `throttle`: Throttle interval in ms.
- `keepPreviousResult`: (default: `false`) Whether or not to keep previous result when the query is fetch again (for example when a variable changes). This can be useful to prevent a flash of empty content.
## Return
- `result`: result data object.
@@ -34,7 +34,6 @@ export default defineComponent({
id: props.id,
}), {
notifyOnNetworkStatusChange: true,
keepPreviousResult: true,
})
const channel = computed(() => result.value?.channel)
@@ -0,0 +1,115 @@
<script lang="ts" setup>
import { useApolloClient, useQuery } from '@vue/apollo-composable'
import gql from 'graphql-tag'
import { computed, ref } from 'vue'
import MessageItem from './MessageItem.vue'
interface Channel {
id: string
label: string
}
const keepPreviousResult = ref(false)
const channelsQuery = useQuery<{ channels: Channel[] }>(gql`
query channels {
channels {
id
label
}
}
`)
const channels = computed(() => channelsQuery.result.value?.channels ?? [])
const selectedChannelId = ref<string | null>(null)
const selectedChannelQuery = useQuery(gql`
query channel ($id: ID!) {
channel (id: $id) {
id
label
messages {
id
text
}
}
}
`, () => ({
id: selectedChannelId.value,
}), () => ({
enabled: !!selectedChannelId.value,
fetchPolicy: 'cache-and-network',
keepPreviousResult: keepPreviousResult.value,
}))
const selectedChannel = computed(() => selectedChannelQuery.result.value?.channel)
const { client: apolloClient } = useApolloClient()
function clearCache () {
apolloClient.clearStore()
}
</script>
<template>
<div class="h-full flex flex-col">
<div class="p-4">
<label>
<input
v-model="keepPreviousResult"
type="checkbox"
>
keepPreviousResult
</label>
<button
class="ml-4 underline"
@click="clearCache"
>
Clear cache
</button>
</div>
<div class="flex h-full">
<div class="flex flex-col">
<button
v-for="channel of channels"
:key="channel.id"
class="channel-btn p-4"
:class="{
'bg-green-200': selectedChannelId === channel.id,
}"
@click="selectedChannelId = channel.id"
>
{{ channel.label }}
</button>
</div>
<div
v-if="selectedChannel"
class="the-channel flex flex-col w-full h-full overflow-auto"
>
<div class="flex-none p-6 border-b border-gray-200 bg-white">
# {{ selectedChannel.label }}
</div>
<div class="flex-1 overflow-y-auto">
<MessageItem
v-for="message of selectedChannel.messages"
:key="message.id"
:message="message"
class="m-2"
/>
</div>
</div>
<div
v-else
class="no-data"
>
No data
</div>
</div>
</div>
</template>
@@ -42,5 +42,9 @@ export const router = createRouter({
path: '/on-result',
component: () => import('./components/OnResult.vue'),
},
{
path: '/keep-previous-result',
component: () => import('./components/KeepPreviousResult.vue'),
},
],
})
@@ -0,0 +1,33 @@
/// <reference types="Cypress" />
describe('keepPreviousResult', () => {
beforeEach(() => {
cy.task('db:reset')
cy.visit('/keep-previous-result')
})
it('keepPreviousResult disabled: should clear previous data', () => {
cy.get('.no-data').should('be.visible')
cy.get('.channel-btn').eq(0).click()
cy.get('.no-data').should('be.visible')
cy.get('.the-channel').should('contain.text', '# General')
cy.get('.no-data').should('not.exist')
cy.get('.channel-btn').eq(1).click()
cy.get('.no-data').should('be.visible')
cy.get('.the-channel').should('contain.text', '# Random')
cy.get('.no-data').should('not.exist')
})
it('keepPreviousResult enabled: should display previous channel', () => {
cy.get('label').contains('keepPreviousResult').get('input[type="checkbox"]').check()
cy.get('.no-data').should('be.visible')
cy.get('.channel-btn').eq(0).click()
cy.get('.no-data').should('be.visible')
cy.get('.the-channel').should('contain.text', '# General')
cy.get('.no-data').should('not.exist')
cy.get('.channel-btn').eq(1).click()
cy.get('.no-data').should('not.exist')
cy.get('.the-channel').should('contain.text', '# General')
cy.get('.the-channel').should('contain.text', '# Random')
})
})
@@ -44,6 +44,7 @@ export interface UseQueryOptions<
throttle?: number
debounce?: number
prefetch?: boolean
keepPreviousResult?: boolean
}
interface SubscribeToMoreItem {
@@ -256,7 +257,7 @@ export function useQueryImpl<
// Make the cache data available to the component immediately
// This prevents SSR hydration mismatches
if (!isServer && (currentOptions.value?.fetchPolicy !== 'no-cache' || currentOptions.value.notifyOnNetworkStatusChange)) {
if (!isServer && !currentOptions.value?.keepPreviousResult && (currentOptions.value?.fetchPolicy !== 'no-cache' || currentOptions.value.notifyOnNetworkStatusChange)) {
const currentResult = query.value.getCurrentResult(false)
if (!currentResult.loading || currentResult.partial || currentOptions.value?.notifyOnNetworkStatusChange) {