# Alert dialog: Async action

> Return a promise from the `onClick` of `<AlertDialogAction />`. The button shows a spinner and the dialog can’t be closed until the promise settles. It closes when it resolves and stays open when it rejects, so people can try again.

Example: https://hextaui.com/docs/alert-dialog/examples/async-action
Component docs: https://hextaui.com/docs/alert-dialog.md

## Add this example

```bash
npx shadcn@latest add https://hextaui.com/r/alert-dialog-async-action.json
```

This adds `components/examples/alert-dialog/async-action.tsx` with the Alert dialog component and the HextaUI theme tokens.

## Source

```tsx title="components/examples/alert-dialog/async-action.tsx"
"use client"

import * as React from "react"
import { IconTrash } from "@tabler/icons-react"

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogMedia,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"

function wait(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms))
}

export function AlertDialogAsyncAction() {
  const [shouldFail, setShouldFail] = React.useState(false)
  const [attempts, setAttempts] = React.useState(0)

  return (
    <div className="flex flex-wrap items-center gap-2">
      <AlertDialog onOpenChange={(open) => open && setAttempts(0)}>
        <AlertDialogTrigger render={<Button variant="destructive" />}>
          Delete project
        </AlertDialogTrigger>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogMedia variant="destructive">
              <IconTrash />
            </AlertDialogMedia>
            <AlertDialogTitle>Delete “Acme website”?</AlertDialogTitle>
            <AlertDialogDescription>
              {attempts > 0
                ? `Deleting failed ${attempts} time${attempts > 1 ? "s" : ""}. Try again.`
                : "All deployments, domains and environment variables will be removed. This can’t be undone."}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              variant="destructive"
              onClick={async () => {
                await wait(1500)
                if (shouldFail) {
                  setAttempts((count) => count + 1)
                  throw new Error("Request failed")
                }
              }}
            >
              Delete project
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
      <Button
        variant="ghost"
        size="sm"
        aria-pressed={shouldFail}
        onClick={() => setShouldFail(!shouldFail)}
      >
        Request will {shouldFail ? "fail" : "succeed"}
      </Button>
    </div>
  )
}
```

## Props in this example

### AlertDialog

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `onOpenChange` | `(open: boolean, details) => void` | – | Not called for closes blocked by a pending action. |

### AlertDialogTrigger

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `render` | `ReactElement \| (props, state) => ReactElement` | `<button>` |  |

### AlertDialogMedia

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `"default" \| "destructive"` | `"default"` |  |

### AlertDialogAction

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `onClick` | `(event) => void \| PromiseLike<unknown>` | – | Return a promise to show a spinner and keep the dialog open until it settles. Call event.preventDefault() to keep it open. |
| `variant` | `ButtonVariant` | `"default"` |  |

## More Alert dialog examples

- [Media](https://hextaui.com/docs/alert-dialog/examples/media.md)
- [Small](https://hextaui.com/docs/alert-dialog/examples/small.md)
- [Detached triggers](https://hextaui.com/docs/alert-dialog/examples/detached-triggers.md)
- [Controlled](https://hextaui.com/docs/alert-dialog/examples/controlled.md)
- [Nested](https://hextaui.com/docs/alert-dialog/examples/nested.md)
- [Long content](https://hextaui.com/docs/alert-dialog/examples/long-content.md)
- [Right to left](https://hextaui.com/docs/alert-dialog/examples/rtl.md)
