Skip to content

Commit

Permalink
feat(return) add isLoading return value (Kong#208)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivos committed Sep 25, 2022
1 parent 1b61853 commit 5276321
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface IResponse<Data = any, Error = any> {
data: Ref<Data | undefined>
error: Ref<Error | undefined>
isValidating: Ref<boolean>
isLoading: Ref<boolean>
mutate: (data?: fetcherFn<Data>, opts?: revalidateOptions) => Promise<void>
}

Expand Down
12 changes: 10 additions & 2 deletions src/use-swrv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ import webPreset from './lib/web-preset'
import SWRVCache from './cache'
import { IConfig, IKey, IResponse, fetcherFn, revalidateOptions } from './types'

type StateRef<Data, Error> = { data: Data, error: Error, isValidating: boolean, revalidate: Function, key: any };
type StateRef<Data, Error> = {
data: Data, error: Error, isValidating: boolean, isLoading: boolean, revalidate: Function, key: any
};

const DATA_CACHE = new SWRVCache<Omit<IResponse, 'mutate'>>()
const REF_CACHE = new SWRVCache<StateRef<any, any>[]>()
Expand Down Expand Up @@ -126,6 +128,7 @@ const mutate = async <Data>(key: string, res: Promise<Data> | Data, cache = DATA
}
r.error = newData.error
r.isValidating = newData.isValidating
r.isLoading = newData.isValidating

const isLast = idx === refs.length - 1
if (!isLast) {
Expand Down Expand Up @@ -223,6 +226,7 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
data: undefined,
error: undefined,
isValidating: true,
isLoading: true,
key: null
}) as StateRef<Data, Error>
}
Expand All @@ -236,9 +240,10 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
if (!keyVal) { return }

const cacheItem = config.cache.get(keyVal)
let newData = cacheItem && cacheItem.data
const newData = cacheItem && cacheItem.data

stateRef.isValidating = true
stateRef.isLoading = !newData
if (newData) {
stateRef.data = newData.data
stateRef.error = newData.error
Expand All @@ -251,6 +256,7 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
(opts?.forceRevalidate !== undefined && !opts?.forceRevalidate)
) {
stateRef.isValidating = false
// stateRef.isLoading = false
return
}

Expand All @@ -262,6 +268,7 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {

if (!shouldRevalidate) {
stateRef.isValidating = false
// stateRef.isLoading = false
return
}
}
Expand All @@ -277,6 +284,7 @@ function useSWRV<Data = any, Error = any> (...args): IResponse<Data, Error> {
await mutate(keyVal, promiseFromCache.data, config.cache, ttl)
}
stateRef.isValidating = false
// stateRef.isLoading = false
PROMISES_CACHE.delete(keyVal)
if (stateRef.error !== undefined) {
const shouldRetryOnError = config.shouldRetryOnError && (opts ? opts.shouldRetryOnError : true)
Expand Down
71 changes: 71 additions & 0 deletions tests/use-swrv.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,77 @@ describe('useSWRV - loading', () => {
expect(wrapper.text()).toBe(':ready')
done()
})

it('should indicate cached data from another key with isLoading false', async () => {
const key = ref(1)
const wrapper = mount(defineComponent({
template: `<div>data: {{ String(data) }}, isValidating: {{ isValidating }}, isLoading: {{ isLoading }}</div>
<button id="inc" v-on:click="inc"/><button id="dec" v-on:click="dec"/>`,
setup () {
const { data, isValidating, isLoading } = useSWRV(() => 'key-' + key.value, async () => {
await loadData()
return 'data-' + key.value
}, { dedupingInterval: 0 })

const inc = () => {
key.value++
}
const dec = () => {
key.value--
}

return { inc, dec, data, isValidating, isLoading }
}
}))

// key 1
// first load ever, cache empty, no data => isLoading true
expect(wrapper.text()).toBe('data: undefined, isValidating: true, isLoading: true')
timeout(100)
await tick(2)
// key-1 data loaded
expect(wrapper.text()).toBe('data: data-1, isValidating: false, isLoading: false')

// key: 1 -> 2
// first load for a key, key cache empty, data from previous key => isLoading true
wrapper.find('#inc').trigger('click')
await tick(2)
expect(wrapper.text()).toBe('data: data-1, isValidating: true, isLoading: true')
timeout(100)
await tick(2)
// data loaded
expect(wrapper.text()).toBe('data: data-2, isValidating: false, isLoading: false')

// key: 2 -> 1
// next load for a key, data from key cache => isLoading false
wrapper.find('#dec').trigger('click')
await tick(2)
expect(wrapper.text()).toBe('data: data-1, isValidating: true, isLoading: false')
timeout(100)
await tick(2)
// data loaded
expect(wrapper.text()).toBe('data: data-1, isValidating: false, isLoading: false')

// key: 1 -> 2
// next load for a key, data from key cache => isLoading false
wrapper.find('#inc').trigger('click')
await tick(2)
expect(wrapper.text()).toBe('data: data-2, isValidating: true, isLoading: false')
timeout(100)
await tick(2)
// data loaded
expect(wrapper.text()).toBe('data: data-2, isValidating: false, isLoading: false')

// key: 2 -> 3
// first load for a key, key cache empty, data from previous key => isLoading true
wrapper.find('#inc').trigger('click')
await tick(2)
expect(wrapper.text()).toBe('data: data-2, isValidating: true, isLoading: true')
timeout(100)
await tick(2)
// data loaded
expect(wrapper.text()).toBe('data: data-3, isValidating: false, isLoading: false')
})
})

describe('useSWRV - mutate', () => {
Expand Down

0 comments on commit 5276321

Please sign in to comment.