Skip to content

Commit 6ac64ad

Browse files
committed
wp
1 parent 665a9e5 commit 6ac64ad

File tree

5 files changed

+176
-200
lines changed

5 files changed

+176
-200
lines changed

docs/directives/async/t-error.md

Lines changed: 13 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,13 @@ The `t-error` directive displays content when an error occurs during async opera
3434

3535
<div t-data="{
3636
error: null,
37-
loading: false,
38-
async fetch(shouldFail) {
39-
this.loading = true
40-
this.error = null
41-
try {
42-
const url = shouldFail
43-
? 'https://jsonplaceholder.typicode.com/invalid'
44-
: 'https://jsonplaceholder.typicode.com/todos/1'
45-
const res = await fetch(url)
46-
if (!res.ok) throw new Error('Failed to fetch data')
47-
const data = await res.json()
48-
alert('Success! Loaded: ' + data.title)
49-
} catch (err) {
50-
this.error = err.message
51-
} finally {
52-
this.loading = false
53-
}
54-
}
37+
loading: false
5538
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
5639
<div class="flex gap-2">
57-
<button t-click="fetch(false)" :disabled="loading" class="px-4 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
40+
<button t-click="(async function(){ loading = true; error = null; try { const url = 'https://jsonplaceholder.typicode.com/todos/1'; const res = await fetch(url); if (!res.ok) throw new Error('Failed to fetch data'); const data = await res.json(); alert('Success! Loaded: ' + data.title); } catch (err) { error = err.message; } finally { loading = false; } })()" :disabled="loading" class="px-4 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
5841
Load Data (Success)
5942
</button>
60-
<button t-click="fetch(true)" :disabled="loading" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50">
43+
<button t-click="(async function(){ loading = true; error = null; try { const url = 'https://jsonplaceholder.typicode.com/invalid'; const res = await fetch(url); if (!res.ok) throw new Error('Failed to fetch data'); const data = await res.json(); alert('Success! Loaded: ' + data.title); } catch (err) { error = err.message; } finally { loading = false; } })()" :disabled="loading" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50">
6144
Load Data (Error)
6245
</button>
6346
</div>
@@ -156,44 +139,16 @@ The `t-error` directive displays content when an error occurs during async opera
156139
<div t-data="{
157140
error: null,
158141
loading: false,
159-
errorType: null,
160-
async fetch(type) {
161-
this.loading = true
162-
this.error = null
163-
this.errorType = type
164-
try {
165-
if (type === 'timeout') {
166-
const controller = new AbortController()
167-
setTimeout(() => controller.abort(), 100)
168-
await fetch('https://httpstat.us/200?sleep=5000', {
169-
signal: controller.signal
170-
})
171-
} else if (type === 'network') {
172-
await fetch('https://invalid-domain-that-does-not-exist-12345.com')
173-
} else {
174-
await fetch('https://jsonplaceholder.typicode.com/invalid')
175-
}
176-
} catch (err) {
177-
if (err.name === 'AbortError') {
178-
this.error = '⏱️ Request timed out after 5 seconds'
179-
} else if (err.name === 'TypeError') {
180-
this.error = '🌐 Network error - check your connection'
181-
} else {
182-
this.error = '❌ ' + err.message
183-
}
184-
} finally {
185-
this.loading = false
186-
}
187-
}
142+
errorType: null
188143
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
189144
<div class="flex gap-2">
190-
<button t-click="fetch('timeout')" :disabled="loading" class="px-3 py-2 bg-orange-600 text-white rounded hover:bg-orange-700 text-sm">
145+
<button t-click="(async function(){ loading = true; error = null; errorType = 'timeout'; try { const controller = new AbortController(); setTimeout(() => controller.abort(), 100); await fetch('https://httpstat.us/200?sleep=5000', { signal: controller.signal }); } catch (err) { if (err.name === 'AbortError') { error = '⏱️ Request timed out after 5 seconds'; } else if (err.name === 'TypeError') { error = '🌐 Network error - check your connection'; } else { error = '❌ ' + err.message; } } finally { loading = false; } })()" :disabled="loading" class="px-3 py-2 bg-orange-600 text-white rounded hover:bg-orange-700 text-sm">
191146
Timeout
192147
</button>
193-
<button t-click="fetch('network')" :disabled="loading" class="px-3 py-2 bg-red-600 text-white rounded hover:bg-red-700 text-sm">
148+
<button t-click="(async function(){ loading = true; error = null; errorType = 'network'; try { await fetch('https://invalid-domain-that-does-not-exist-12345.com'); } catch (err) { if (err.name === 'AbortError') { error = '⏱️ Request timed out after 5 seconds'; } else if (err.name === 'TypeError') { error = '🌐 Network error - check your connection'; } else { error = '❌ ' + err.message; } } finally { loading = false; } })()" :disabled="loading" class="px-3 py-2 bg-red-600 text-white rounded hover:bg-red-700 text-sm">
194149
Network
195150
</button>
196-
<button t-click="fetch('404')" :disabled="loading" class="px-3 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 text-sm">
151+
<button t-click="(async function(){ loading = true; error = null; errorType = '404'; try { await fetch('https://jsonplaceholder.typicode.com/invalid'); } catch (err) { if (err.name === 'AbortError') { error = '⏱️ Request timed out after 5 seconds'; } else if (err.name === 'TypeError') { error = '🌐 Network error - check your connection'; } else { error = '❌ ' + err.message; } } finally { loading = false; } })()" :disabled="loading" class="px-3 py-2 bg-purple-600 text-white rounded hover:bg-purple-700 text-sm">
197152
404 Error
198153
</button>
199154
</div>
@@ -312,25 +267,8 @@ Add retry button for failed requests:
312267
error: null,
313268
loading: false,
314269
retries: 0,
315-
data: null,
316-
async fetch() {
317-
this.loading = true
318-
this.error = null
319-
try {
320-
// Succeed after 3 attempts
321-
if (this.retries < 2) {
322-
throw new Error('Request failed. Please try again.')
323-
}
324-
const res = await fetch('https://jsonplaceholder.typicode.com/todos/1')
325-
this.data = await res.json()
326-
this.retries = 0
327-
} catch (err) {
328-
this.error = err.message
329-
} finally {
330-
this.loading = false
331-
}
332-
}
333-
}" t-init="$context.fetch()" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
270+
data: null
271+
}" t-init="(async function(){ loading = true; error = null; try { if (retries < 2) { throw new Error('Request failed. Please try again.'); } const res = await fetch('https://jsonplaceholder.typicode.com/todos/1'); data = await res.json(); retries = 0; } catch (err) { error = err.message; } finally { loading = false; } })()" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
334272
<div t-show="loading" class="p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded">
335273
<p class="text-blue-700 dark:text-blue-300">Loading...</p>
336274
</div>
@@ -342,7 +280,7 @@ Add retry button for failed requests:
342280
Attempts: <span t-text="retries"></span> of 3
343281
</p>
344282
</div>
345-
<button t-click="retries++; fetch()" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700">
283+
<button t-click="(async function(){ retries++; loading = true; error = null; try { if (retries < 2) { throw new Error('Request failed. Please try again.'); } const res = await fetch('https://jsonplaceholder.typicode.com/todos/1'); data = await res.json(); retries = 0; } catch (err) { error = err.message; } finally { loading = false; } })()" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700">
346284
🔄 Retry
347285
</button>
348286
</div>
@@ -521,32 +459,13 @@ Show fallback content on error:
521459
<div t-data="{
522460
data: null,
523461
error: null,
524-
loading: false,
525-
async load(shouldFail) {
526-
this.loading = true
527-
this.error = null
528-
this.data = null
529-
try {
530-
await new Promise(resolve => setTimeout(resolve, 1000))
531-
if (shouldFail) {
532-
throw new Error('Unable to connect to server')
533-
}
534-
this.data = {
535-
title: 'Dashboard',
536-
stats: { users: 1234, posts: 567, comments: 8901 }
537-
}
538-
} catch (err) {
539-
this.error = err.message
540-
} finally {
541-
this.loading = false
542-
}
543-
}
462+
loading: false
544463
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-4">
545464
<div class="flex gap-2">
546-
<button t-click="load(false)" :disabled="loading" class="px-4 py-2 bg-pine-600 text-white rounded hover:bg-pine-700 disabled:opacity-50">
465+
<button t-click="(async function(){ loading = true; error = null; data = null; try { await new Promise(resolve => setTimeout(resolve, 1000)); data = { title: 'Dashboard', stats: { users: 1234, posts: 567, comments: 8901 } }; } catch (err) { error = err.message; } finally { loading = false; } })()" :disabled="loading" class="px-4 py-2 bg-pine-600 text-white rounded hover:bg-pine-700 disabled:opacity-50">
547466
Load Successfully
548467
</button>
549-
<button t-click="load(true)" :disabled="loading" class="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 disabled:opacity-50">
468+
<button t-click="(async function(){ loading = true; error = null; data = null; try { await new Promise(resolve => setTimeout(resolve, 1000)); throw new Error('Unable to connect to server'); } catch (err) { error = err.message; } finally { loading = false; } })()" :disabled="loading" class="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 disabled:opacity-50">
550469
Load with Error
551470
</button>
552471
</div>

docs/directives/async/t-loading.md

Lines changed: 16 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,9 @@ The `t-loading` directive shows content only during async operations. It automat
2020
```
2121

2222
<div t-data="{
23-
loading: false,
24-
startLoading() {
25-
this.loading = true
26-
setTimeout(() => { this.loading = false }, 2000)
27-
}
23+
loading: false
2824
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
29-
<button t-click="startLoading()" :disabled="loading" class="px-6 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
25+
<button t-click="(function(){ loading = true; setTimeout(() => { loading = false }, 2000) })()" :disabled="loading" class="px-6 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
3026
<span t-show="!loading">Start Loading</span>
3127
<span t-show="loading">Loading...</span>
3228
</button>
@@ -93,20 +89,9 @@ Show placeholder content while loading:
9389

9490
<div t-data="{
9591
loading: false,
96-
data: null,
97-
async loadContent() {
98-
this.loading = true
99-
this.data = null
100-
await new Promise(resolve => setTimeout(resolve, 2000))
101-
this.data = {
102-
title: 'Article Title',
103-
author: 'John Doe',
104-
content: 'This is the article content that was loaded from the server.'
105-
}
106-
this.loading = false
107-
}
108-
}" t-init="$context.loadContent()" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-4">
109-
<button t-click="loadContent()" :disabled="loading" class="px-4 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
92+
data: null
93+
}" t-init="(async function(){ loading = true; data = null; await new Promise(resolve => setTimeout(resolve, 2000)); data = { title: 'Article Title', author: 'John Doe', content: 'This is the article content that was loaded from the server.' }; loading = false; })()" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-4">
94+
<button t-click="(async function(){ loading = true; data = null; await new Promise(resolve => setTimeout(resolve, 2000)); data = { title: 'Article Title', author: 'John Doe', content: 'This is the article content that was loaded from the server.' }; loading = false; })()" :disabled="loading" class="px-4 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
11095
Reload
11196
</button>
11297

@@ -151,18 +136,9 @@ Show loading progress:
151136

152137
<div t-data="{
153138
progress: 0,
154-
loading: false,
155-
async load() {
156-
this.loading = true
157-
this.progress = 0
158-
for (let i = 0; i <= 100; i += 10) {
159-
await new Promise(resolve => setTimeout(resolve, 150))
160-
this.progress = i
161-
}
162-
this.loading = false
163-
}
139+
loading: false
164140
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-4">
165-
<button t-click="load()" :disabled="loading" class="px-6 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
141+
<button t-click="(async function(){ loading = true; progress = 0; for (let i = 0; i <= 100; i += 10) { await new Promise(resolve => setTimeout(resolve, 150)); progress = i; } loading = false; })()" :disabled="loading" class="px-6 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
166142
<span t-show="!loading">Start Loading</span>
167143
<span t-show="loading">Loading...</span>
168144
</button>
@@ -206,18 +182,9 @@ Show loading progress:
206182
<div t-data="{
207183
step: 0,
208184
loading: false,
209-
messages: ['🔌 Connecting to server...', '📦 Loading data...', '⚙️ Processing...', '✨ Almost done...'],
210-
async load() {
211-
this.loading = true
212-
for (let i = 0; i < this.messages.length; i++) {
213-
this.step = i
214-
await new Promise(resolve => setTimeout(resolve, 1200))
215-
}
216-
this.loading = false
217-
this.step = 0
218-
}
185+
messages: ['🔌 Connecting to server...', '📦 Loading data...', '⚙️ Processing...', '✨ Almost done...']
219186
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-4">
220-
<button t-click="load()" :disabled="loading" class="px-6 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
187+
<button t-click="(async function(){ loading = true; for (let i = 0; i < messages.length; i++) { step = i; await new Promise(resolve => setTimeout(resolve, 1200)); } loading = false; step = 0; })()" :disabled="loading" class="px-6 py-2 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50">
221188
Start Process
222189
</button>
223190

@@ -246,17 +213,9 @@ Show loading state inline with content:
246213

247214
<div t-data="{
248215
saving: false,
249-
saved: false,
250-
async save() {
251-
this.saving = true
252-
this.saved = false
253-
await new Promise(resolve => setTimeout(resolve, 1500))
254-
this.saving = false
255-
this.saved = true
256-
setTimeout(() => { this.saved = false }, 2000)
257-
}
216+
saved: false
258217
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
259-
<button t-click="save()" :disabled="saving" class="px-6 py-3 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50 flex items-center gap-2">
218+
<button t-click="(async function(){ saving = true; saved = false; await new Promise(resolve => setTimeout(resolve, 1500)); saving = false; saved = true; setTimeout(() => { saved = false }, 2000); })()" :disabled="saving" class="px-6 py-3 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50 flex items-center gap-2">
260219
<div t-show="saving" class="animate-spin rounded-full h-4 w-4 border-2 border-white border-t-transparent"></div>
261220
<span t-show="!saving && !saved">💾 Save Changes</span>
262221
<span t-show="saving">Saving...</span>
@@ -290,17 +249,9 @@ Disable buttons during loading:
290249

291250
<div t-data="{
292251
submitting: false,
293-
success: false,
294-
async submit() {
295-
this.submitting = true
296-
this.success = false
297-
await new Promise(resolve => setTimeout(resolve, 2000))
298-
this.submitting = false
299-
this.success = true
300-
setTimeout(() => { this.success = false }, 3000)
301-
}
252+
success: false
302253
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-3">
303-
<button t-click="submit()" :disabled="submitting" class="w-full px-6 py-3 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium flex items-center justify-center gap-2">
254+
<button t-click="(async function(){ submitting = true; success = false; await new Promise(resolve => setTimeout(resolve, 2000)); submitting = false; success = true; setTimeout(() => { success = false }, 3000); })()" :disabled="submitting" class="w-full px-6 py-3 bg-pine-600 text-white rounded-lg hover:bg-pine-700 disabled:opacity-50 disabled:cursor-not-allowed font-medium flex items-center justify-center gap-2">
304255
<div t-show="submitting" class="animate-spin rounded-full h-5 w-5 border-2 border-white border-t-transparent"></div>
305256
<span t-show="!submitting && !success">Submit Form</span>
306257
<span t-show="submitting">Submitting...</span>
@@ -343,26 +294,14 @@ Handle multiple async operations:
343294
loadingUsers: false,
344295
loadingPosts: false,
345296
users: null,
346-
posts: null,
347-
async loadUsers() {
348-
this.loadingUsers = true
349-
await new Promise(resolve => setTimeout(resolve, 1500))
350-
this.users = ['Alice', 'Bob', 'Charlie']
351-
this.loadingUsers = false
352-
},
353-
async loadPosts() {
354-
this.loadingPosts = true
355-
await new Promise(resolve => setTimeout(resolve, 2000))
356-
this.posts = ['Post 1', 'Post 2', 'Post 3']
357-
this.loadingPosts = false
358-
}
297+
posts: null
359298
}" class="p-6 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 my-6 space-y-4">
360299
<div class="flex gap-2">
361-
<button t-click="loadUsers()" :disabled="loadingUsers" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50">
300+
<button t-click="(async function(){ loadingUsers = true; await new Promise(resolve => setTimeout(resolve, 1500)); users = ['Alice', 'Bob', 'Charlie']; loadingUsers = false; })()" :disabled="loadingUsers" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50">
362301
<span t-show="!loadingUsers">Load Users</span>
363302
<span t-show="loadingUsers">Loading...</span>
364303
</button>
365-
<button t-click="loadPosts()" :disabled="loadingPosts" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50">
304+
<button t-click="(async function(){ loadingPosts = true; await new Promise(resolve => setTimeout(resolve, 2000)); posts = ['Post 1', 'Post 2', 'Post 3']; loadingPosts = false; })()" :disabled="loadingPosts" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50">
366305
<span t-show="!loadingPosts">Load Posts</span>
367306
<span t-show="loadingPosts">Loading...</span>
368307
</button>

0 commit comments

Comments
 (0)