Skip to content

Commit 86b455f

Browse files
committed
Add "abort request" experiment client-side code
1 parent 0210b2c commit 86b455f

File tree

2 files changed

+123
-14
lines changed

2 files changed

+123
-14
lines changed

pages/experiments/index.vue

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<p>{{ group.target }}</p>
66
<ul class="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3">
77
<li v-for="experiment in group.experiments" :key="experiment.route">
8-
<WlExperimentCard :experiment="experiment" />
8+
<WlExperimentCard :experiment="experiment"/>
99
</li>
1010
</ul>
1111
</div>
@@ -27,44 +27,87 @@ const groups: ExperimentGroup[] = [
2727
{
2828
target: 'Forms & Input',
2929
experiments: [
30-
{ name: 'Button', route: '/experiments/forms-input/button' },
31-
{ name: 'Progress', route: '/experiments/forms-input/progress' },
32-
{ name: 'Input', route: '/experiments/forms-input/input' },
33-
{ name: 'Select', route: '/experiments/forms-input/select' },
34-
{ name: 'Badge', route: '/experiments/forms-input/badge' }
30+
{
31+
name: 'Button',
32+
route: '/experiments/forms-input/button'
33+
},
34+
{
35+
name: 'Progress',
36+
route: '/experiments/forms-input/progress'
37+
},
38+
{
39+
name: 'Input',
40+
route: '/experiments/forms-input/input'
41+
},
42+
{
43+
name: 'Select',
44+
route: '/experiments/forms-input/select'
45+
},
46+
{
47+
name: 'Badge',
48+
route: '/experiments/forms-input/badge'
49+
}
3550
]
3651
},
3752
{
3853
target: 'Micro-interactions',
3954
experiments: [
40-
{ name: 'Scroll', route: '/experiments/micro-interactions/scroll' },
41-
{ name: 'SVG', route: '/experiments/micro-interactions/svg' },
42-
{ name: 'Drag & Drop', route: '/experiments/micro-interactions/drag-n-drop' },
43-
{ name: 'GSAP', route: '/experiments/micro-interactions/gsap' }
55+
{
56+
name: 'Scroll',
57+
route: '/experiments/micro-interactions/scroll'
58+
},
59+
{
60+
name: 'SVG',
61+
route: '/experiments/micro-interactions/svg'
62+
},
63+
{
64+
name: 'Drag & Drop',
65+
route: '/experiments/micro-interactions/drag-n-drop'
66+
},
67+
{
68+
name: 'GSAP',
69+
route: '/experiments/micro-interactions/gsap'
70+
},
71+
{
72+
name: 'Abort Request',
73+
route: '/experiments/micro-interactions/abort-request'
74+
}
4475
]
4576
},
4677
{
4778
target: 'Navigation',
4879
experiments: [
49-
{ name: 'Transitions', route: '/experiments/navigation/transitions' }
80+
{
81+
name: 'Transitions',
82+
route: '/experiments/navigation/transitions'
83+
}
5084
]
5185
},
5286
{
5387
target: 'Authentication',
5488
experiments: [
55-
{ name: 'Third-party login', route: '/experiments/authentication/third-party-login' }
89+
{
90+
name: 'Third-party login',
91+
route: '/experiments/authentication/third-party-login'
92+
}
5693
]
5794
},
5895
{
5996
target: 'Real-time Communication',
6097
experiments: [
61-
{ name: 'Supabase', route: '/experiments/rtc/supabase' }
98+
{
99+
name: 'Supabase',
100+
route: '/experiments/rtc/supabase'
101+
}
62102
]
63103
},
64104
{
65105
target: 'Threading',
66106
experiments: [
67-
{ name: 'Web Workers', route: '/experiments/threading/web-workers' }
107+
{
108+
name: 'Web Workers',
109+
route: '/experiments/threading/web-workers'
110+
}
68111
]
69112
}
70113
]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<template>
2+
<NuxtLayout name="home">
3+
<WlContainer class="flex flex-col gap-3 p-3">
4+
<p>Cancel an event using an <code>AbortSignal</code> instance:</p>
5+
<WlExperimentCanvas>
6+
<div class="flex items-center gap-3">
7+
<WlButton ref="button" variant="primary" @click="listeners.click">Click</WlButton>
8+
<WlButton ref="button" variant="secondary" @click="listeners.cancel">Cancel</WlButton>
9+
<p>Result: <code>{{ result }}</code></p>
10+
</div>
11+
</WlExperimentCanvas>
12+
</WlContainer>
13+
</NuxtLayout>
14+
</template>
15+
16+
<script setup lang="ts">
17+
import { ref } from 'vue'
18+
19+
import WlButton from '~/components/experiments/forms-input/buttons/WlButton.vue'
20+
import WlExperimentCanvas from '~/components/shared/experiments/WlExperimentCanvas.vue'
21+
import WlContainer from '~/components/shared/layout/WlContainer.vue'
22+
23+
const result = ref('<empty>')
24+
const loading = ref(false)
25+
let abortController = new AbortController()
26+
27+
class UserCancelledError extends Error {
28+
constructor () {
29+
super('User cancelled the request.')
30+
this.name = 'UserCancelledError'
31+
}
32+
}
33+
34+
const listeners = {
35+
async click () {
36+
loading.value = true
37+
38+
try {
39+
const response = await fetch('/api/abort-request', {
40+
signal: abortController.signal
41+
})
42+
result.value = await response.json()
43+
} catch (error) {
44+
if (error instanceof UserCancelledError) {
45+
result.value = '<cancelled>'
46+
} else {
47+
throw error
48+
}
49+
}
50+
51+
loading.value = false
52+
},
53+
async cancel () {
54+
if (!loading.value) {
55+
alert('No operation in progress.')
56+
57+
return
58+
}
59+
60+
abortController.abort(new UserCancelledError())
61+
loading.value = false
62+
63+
abortController = new AbortController()
64+
}
65+
}
66+
</script>

0 commit comments

Comments
 (0)