Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(useFetch): change internal logic #549

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fb7aff4
fix: wrong payloadType assigment
userquin May 30, 2021
720db80
fix: correct request `content-type` header
userquin May 30, 2021
a4b0385
fix: handle request `content-type` header before calling fetch
userquin May 30, 2021
2edb23f
fix: adjust logic to remove headers from context
userquin May 30, 2021
a70523b
chore: clean up and add some comments
userquin May 30, 2021
f80e708
chore: encode object when is not URLSearchParams nor a string
userquin May 30, 2021
f939d9d
chore: encode using async tasks
userquin May 30, 2021
b7f94ac
chore: reorder execute method logic
userquin May 30, 2021
31857bc
chore: minor changes to remove content-type header for multipart/form…
userquin May 30, 2021
152a653
feat: added `multipart/form-data` and `application/x-www-form-urlenco…
userquin May 30, 2021
f6ec788
chore: allow call setMethod if payloadType not modified
userquin Jun 2, 2021
bfc78ca
chore: allow call setMethod if payloadType not modified
userquin Jun 2, 2021
9148530
chore: allow change the payload not the method
userquin Jun 2, 2021
f09f227
fix: move configuring method inside anom fun
userquin Jun 2, 2021
7025a4d
fix: max file upload input size 10KB
userquin Jun 2, 2021
99c356b
chore: modify form url encoding logic
userquin Jun 3, 2021
37221e4
chore: fix typo
userquin Jun 3, 2021
bd82304
chore: fix typo on max file size validity message
userquin Jun 3, 2021
2ee56d8
fix: avoid double encoding on `json` payload
userquin Jun 3, 2021
5787734
chore: handle raw object also for `formData`
userquin Jun 3, 2021
a9adad1
feat: custom response handler
userquin Jun 3, 2021
893018c
chore: remove default values destructuring custom response call
userquin Jun 3, 2021
718ae14
chore: adjust custom response jsdoc
userquin Jun 3, 2021
69cb1e4
chore: modify toFormData to deal with nested objects
userquin Jun 3, 2021
ad81a58
chore: remove nested if statements on toFormData
userquin Jun 3, 2021
9f7a825
chore: remove method from `beforeFetch` context to avoid changing it
userquin Jun 3, 2021
d178a7a
chore: document why we need to remove `content-type` header for multi…
userquin Jun 3, 2021
8d1f05f
chore: add docs to index.md + some wording on events entry
userquin Jun 3, 2021
b5986bc
chore: second round for docs
userquin Jun 3, 2021
ba8c165
docs: add custom response handler on type declarations
userquin Jun 3, 2021
ef2b3e4
docs: fix missing breaks on advanced usage example
userquin Jun 3, 2021
b8f3e66
docs: include nested objects handling for raw objects for `formEncode…
userquin Jun 3, 2021
147c5e8
docs: reordering of comments regarding the use of nested objects on `…
userquin Jun 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
223 changes: 190 additions & 33 deletions packages/core/useFetch/demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,44 @@ import { useToggle } from '@vueuse/shared'
import { useFetch } from '.'

const url = ref('https://httpbin.org/get')
const fieldA = ref('')
const fieldB = ref('')
const file = ref<File | null>(null)
const fileField = ref(null)
const refetch = ref(false)
const state = ref(0)

const toggleRefetch = useToggle(refetch)
const go = () => {
state.value = 0
}
const goWWWFormUrlEncoded = () => {
state.value = 1
}
const goMultipart = () => {
state.value = 2
}

const buildFormData = async() => {
const formData = new FormData()
formData.append(
'fieldB',
new Blob(
[JSON.stringify({ message: `Multipart B: ${Math.random()}` })],
{ type: 'application/json' },
),
'test-multipart-b.json',
)
formData.append(
'fieldC',
new Blob(
[JSON.stringify({ message: `Multipart C: ${Math.random()}` })],
{ type: 'application/json' },
),
'test-multipart-c.json',
)
return formData
}

const {
data,
Expand All @@ -29,45 +64,167 @@ const text = stringify(reactive({
data,
}))

const {
data: dataURLEncoded,
error: errorURLEncoded,
statusCode: statusCodeURLEncoded,
isFetching: isFetchingURLEncoded,
isFinished: isFinishedURLEncoded,
execute: executeURLEncoded,
} = useFetch(
'https://httpbin.org/post',
{
immediate: false,
beforeFetch: async() => {
return {
options: {
body: {
fieldA: fieldA.value,
fieldB: fieldB.value,
},
},
}
},
},
).post(
null,
'formEncoded',
)

const textURLEncoded = stringify(reactive({
isFinishedURLEncoded,
isFetchingURLEncoded,
statusCodeURLEncoded,
errorURLEncoded,
dataURLEncoded,
}))

const {
data: dataMultipart,
error: errorMultipart,
statusCode: statusCodeMultipart,
isFetching: isFetchingMultipart,
isFinished: isFinishedMultipart,
execute: executeMultipart,
} = useFetch(
'https://httpbin.org/post',
{
immediate: false,
beforeFetch: async() => {
const body = await buildFormData()
if (file.value)
body.append('fieldA', file.value, file.value.name)

return {
options: {
// we are testing here the header is removed on internal execute call
headers: { 'Content-Type': 'multipart/form-data' },
body,
},
}
},
},
).post(null, 'formData') // <== do not remove it

const textMultipart = stringify(reactive({
isFinishedMultipart,
isFetchingMultipart,
statusCodeMultipart,
errorMultipart,
dataMultipart,
}))

const sendMultipartUpload = () => {
setTimeout(executeMultipart, 0)
}
const updateFile = async() => {
if (fileField.value.files.length > 0) {
file.value = fileField.value.files[0]
if (file.value.size > 10240)
fileField.value.setCustomValidity('Maximum file size 10KB')
else
fileField.value.setCustomValidity('')
}
else {
file.value = null
fileField.value.setCustomValidity('')
}
}

</script>

<template>
<div>
<div>
<note>The following URLs can be used to test different features of useFetch</note>
<div class="mt-2">
Normal Request:
<code>
https://httpbin.org/get
</code>
</div>
<template v-if="state === 2">
<note>Fill the following file input and click on execute button (the execution will add 2 blobs to the file)</note>
<br>
<form @submit.prevent="sendMultipartUpload">
<label for="form-file">Select a file smaller than 10kB : </label>
<input id="form-file" ref="fileField" placeholder="Field A" type="file" @change="updateFile" />
<br>
<button type="submit">
Execute multipart
</button>
<button type="button" @click="go">
Back
</button>
</form>
<pre lang="yaml">{{ textMultipart }}</pre>
</template>
<template v-else-if="state === 1">
<note>Fill the following fields and click on execute button (you can enter symbols like &amp; or &lt; to see they are encoded)</note>
<input v-model="fieldA" placeholder="Field A" type="text">
<input v-model="fieldB" placeholder="Field B" type="text">
<button @click="executeURLEncoded">
Execute Form URL Encoded
</button>
<button @click="go">
Back
</button>
<pre lang="yaml">{{ textURLEncoded }}</pre>
</template>
<template v-else>
<div>
Abort Request:
<code>
https://httpbin.org/delay/10
</code>
<note>The following URLs can be used to test different features of useFetch</note>
<div class="mt-2">
Normal Request:
<code>
https://httpbin.org/get
</code>
</div>
<div>
Abort Request:
<code>
https://httpbin.org/delay/10
</code>
</div>
<div>
Response Error:
<code>
http://httpbin.org/status/500
</code>
</div>
</div>
<div>
Response Error:
<code>
http://httpbin.org/status/500
</code>
</div>
</div>

<input v-model="url" type="text">
<button @click="execute">
Execute
</button>
<button @click="toggleRefetch">
<carbon-checkmark v-if="refetch" />
<carbon-error v-else />
<input v-model="url" type="text">
<button @click="execute">
Execute
</button>
<button @click="toggleRefetch">
<carbon-checkmark v-if="refetch" />
<carbon-error v-else />

<span class="ml-2">{{ refetch ? 'Refetch On': 'Refetch Off' }}</span>
</button>
<button v-if="canAbort" class="orange" @click="abort">
Abort
</button>
<pre lang="yaml">{{ text }}</pre>
<span class="ml-2">{{ refetch ? 'Refetch On': 'Refetch Off' }}</span>
</button>
<button @click="goWWWFormUrlEncoded">
Test Form URL Encoded
</button>
<button @click="goMultipart">
Test Multipart
</button>
<button v-if="canAbort" class="orange" @click="abort">
Abort
</button>
<pre lang="yaml">{{ text }}</pre>
</template>
</div>
</template>