Skip to content

Commit

Permalink
fix(useFetch): immediately modify the status after the request is com…
Browse files Browse the repository at this point in the history
…pleted (#3603)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
tolking and antfu committed Dec 4, 2023
1 parent 31401be commit 3456d1b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 61 deletions.
8 changes: 8 additions & 0 deletions packages/core/useFetch/index.test.ts
Expand Up @@ -734,4 +734,12 @@ describe.skipIf(isBelowNode18)('useFetch', () => {
expect(fetchSpyHeaders()['Content-Type']).toBe(undefined)
})
})

it('should be modified the request status after the request is completed', async () => {
const { isFetching, isFinished, execute } = useFetch('https://example.com', { immediate: false })

await execute()
expect(isFetching.value).toBe(false)
expect(isFinished.value).toBe(true)
})
})
119 changes: 58 additions & 61 deletions packages/core/useFetch/index.ts
Expand Up @@ -454,70 +454,67 @@ export function useFetch<T>(url: MaybeRefOrGetter<string>, ...args: any[]): UseF
if (timer)
timer.start()

return new Promise<Response | null>((resolve, reject) => {
fetch(
context.url,
{
...defaultFetchOptions,
...context.options,
headers: {
...headersToObject(defaultFetchOptions.headers),
...headersToObject(context.options?.headers),
},
return fetch(
context.url,
{
...defaultFetchOptions,
...context.options,
headers: {
...headersToObject(defaultFetchOptions.headers),
...headersToObject(context.options?.headers),
},
)
.then(async (fetchResponse) => {
response.value = fetchResponse
statusCode.value = fetchResponse.status

responseData = await fetchResponse[config.type]()

// see: https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
if (!fetchResponse.ok) {
data.value = initialData || null
throw new Error(fetchResponse.statusText)
}

if (options.afterFetch) {
({ data: responseData } = await options.afterFetch({
data: responseData,
response: fetchResponse,
}))
}
},
)
.then(async (fetchResponse) => {
response.value = fetchResponse
statusCode.value = fetchResponse.status

responseData = await fetchResponse[config.type]()

// see: https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
if (!fetchResponse.ok) {
data.value = initialData || null
throw new Error(fetchResponse.statusText)
}

if (options.afterFetch) {
({ data: responseData } = await options.afterFetch({
data: responseData,
response: fetchResponse,
}))
}
data.value = responseData

responseEvent.trigger(fetchResponse)
return fetchResponse
})
.catch(async (fetchError) => {
let errorData = fetchError.message || fetchError.name

if (options.onFetchError) {
({ error: errorData, data: responseData } = await options.onFetchError({
data: responseData,
error: fetchError,
response: response.value,
}))
}

error.value = errorData
if (options.updateDataOnError)
data.value = responseData

responseEvent.trigger(fetchResponse)
return resolve(fetchResponse)
})
.catch(async (fetchError) => {
let errorData = fetchError.message || fetchError.name

if (options.onFetchError) {
({ error: errorData, data: responseData } = await options.onFetchError({
data: responseData,
error: fetchError,
response: response.value,
}))
}

error.value = errorData
if (options.updateDataOnError)
data.value = responseData

errorEvent.trigger(fetchError)
if (throwOnFailed)
return reject(fetchError)

return resolve(null)
})
.finally(() => {
if (currentExecuteCounter === executeCounter)
loading(false)
if (timer)
timer.stop()
finallyEvent.trigger(null)
})
})
errorEvent.trigger(fetchError)
if (throwOnFailed)
throw fetchError
return null
})
.finally(() => {
if (currentExecuteCounter === executeCounter)
loading(false)
if (timer)
timer.stop()
finallyEvent.trigger(null)
})
}

const refetch = toRef(options.refetch)
Expand Down

0 comments on commit 3456d1b

Please sign in to comment.