diff --git a/src/composables/useFetch.js b/src/composables/useFetch.js index c2816daba..1f3591875 100644 --- a/src/composables/useFetch.js +++ b/src/composables/useFetch.js @@ -56,6 +56,7 @@ export function useFetch(url, options = {}) { const modalStore = useModalStore(); const isLoading = ref(false); const data = ref(null); + const isSuccess = ref(null); const validationError = ref(null); let lastRequestController = null; @@ -91,12 +92,15 @@ export function useFetch(url, options = {}) { } isLoading.value = true; + isSuccess.value = null; try { const result = await ofetchInstance(unref(url), opts); data.value = result; validationError.value = null; + isSuccess.value = true; } catch (e) { data.value = null; + isSuccess.value = false; if (signal) { e.aborted = signal.aborted; @@ -120,6 +124,7 @@ export function useFetch(url, options = {}) { return { data, + isSuccess, validationError, isLoading, fetch, diff --git a/src/composables/useFetch.mdx b/src/composables/useFetch.mdx index 87d84ebb9..baede51c6 100644 --- a/src/composables/useFetch.mdx +++ b/src/composables/useFetch.mdx @@ -58,7 +58,7 @@ const body = {title: 'abc'}; const url = ref(submissionPostApiUrl); // url, query and body can be normal objects or Refs -const {data, validationError, fetch} = useFetch(url, { +const {data, iSuccess, validationError, fetch} = useFetch(url, { method: 'POST', body, // important if we expect endpoint to validate user input @@ -70,6 +70,7 @@ await fetch(); console.log(validationError.value); // null console.log(data.value); // {...} data returned from server +console.log(data.isSuccess); // true ``` ### POST 4xx with validation error @@ -93,6 +94,25 @@ console.log(validationError.value); // {title: ['Unsupported characters']} console.log(data.value); // null ``` +### POST 500 + +```javascript +const body = {title: 'abc'}; +const url = ref(submissionPostApiUrl); + +// url, query and body can be normal objects or Refs +const {data, isSuccess, fetch} = useFetch(url, { + method: 'POST', + body, +}); + +await fetch(); + +// Useful when some follow-up action should be triggered based on successfull request +console.log(isSuccess.value); // false +console.log(data.value); // null +``` + ### PUT 200 ```javascript diff --git a/src/composables/useFetch.test.js b/src/composables/useFetch.test.js index 7d7716587..85f076610 100644 --- a/src/composables/useFetch.test.js +++ b/src/composables/useFetch.test.js @@ -65,6 +65,10 @@ export const restHandlers = [ ); }), + http.post('http://mock/post/status500', async ({request}) => { + return HttpResponse.json({}, {status: 500}); + }), + http.post('http://mock/put/status200', async ({request}) => { const postBody = await request.json(); @@ -127,7 +131,7 @@ describe('typical uses', () => { test('POST 200 request', async () => { const body = {title: 'abc'}; const url = ref('http://mock/post/status200'); - const {data, validationError, fetch} = useFetch(url, { + const {data, isSuccess, validationError, fetch} = useFetch(url, { method: 'POST', body, expectValidationError: true, @@ -138,6 +142,24 @@ describe('typical uses', () => { expect(validationError.value).toBe(null); expect(data.value).toStrictEqual(body); + expect(isSuccess.value).toBe(true); + }); + + test('POST 500 request', async () => { + const body = {title: 'abc'}; + const url = ref('http://mock/post/status500'); + const {data, fetch, isSuccess} = useFetch(url, { + method: 'POST', + body, + }); + + expect(isSuccess.value).toBe(null); + + await fetch(); + + expect(isSuccess.value).toBe(false); + + expect(data.value).toStrictEqual(null); }); test('POST 400 validation error request', async () => {