Async Event Callbacks

+15 Mana ✨

Many event handlers need to perform async operations like API calls. Let's explore patterns for handling async callbacks elegantly.

Basic Async Callback

svelte
<!-- Child.svelte -->
<script>
  let { onsave } = $props();
  let isSaving = $state(false);
  
  async function handleSave() {
    isSaving = true;
    try {
      await onsave(formData);
    } finally {
      isSaving = false;
    }
  }
</script>

<button onclick={handleSave} disabled={isSaving}>
  {isSaving ? 'Saving...' : 'Save'}
</button>
svelte
<!-- Parent.svelte -->
<script>
  async function saveToApi(data) {
    const response = await fetch('/api/save', {
      method: 'POST',
      body: JSON.stringify(data)
    });
    if (!response.ok) throw new Error('Save failed');
  }
</script>

<Child onsave={saveToApi} />

Handling Errors

The child can handle errors from async callbacks:

svelte
<!-- Child.svelte -->
<script>
  let { onsave } = $props();
  let isSaving = $state(false);
  let error = $state(null);
  
  async function handleSave() {
    isSaving = true;
    error = null;
    
    try {
      await onsave(formData);
    } catch (e) {
      error = e.message;
    } finally {
      isSaving = false;
    }
  }
</script>

{#if error}
  <div class="error">{error}</div>
{/if}

<button onclick={handleSave} disabled={isSaving}>
  {isSaving ? 'Saving...' : 'Save'}
</button>

Returning Data from Callbacks

Callbacks can return values:

svelte
<!-- Child.svelte -->
<script>
  let { onvalidate } = $props();
  
  async function handleSubmit() {
    const isValid = await onvalidate(formData);
    if (isValid) {
      // Proceed with submission
    }
  }
</script>
svelte
<!-- Parent.svelte -->
<Child onvalidate={async (data) => {
  const response = await fetch('/api/validate', { body: JSON.stringify(data) });
  return response.ok;
}} />

TypeScript for Async Callbacks

svelte
<script lang="ts">
  type Props = {
    onsave: (data: FormData) => Promise<void>;
    onvalidate?: (data: FormData) => Promise<boolean>;
    oncancel?: () => void; // Sync callback
  };
  
  let { onsave, onvalidate, oncancel }: Props = $props();
</script>

šŸ“– Props documentation

āœ“ Completed