# Next.js, passing an id to a server action

> Learn two ways to pass an id to a Next.js server action: a hidden input read from FormData, or binding the id to the action with bind().

Author: Flavio Copes | Published: 2024-09-19 | Canonical: https://flaviocopes.com/passing-an-id-to-a-server-action/

My goal was to pass an `id` to a server action.

Simplest thing is adding that as an hidden input field in the form.

Here’s a todo list example:

```typescript
'use client'

import { use } from 'react'
import type { Todo } from '@/app/types.ts'
import { deleteTodo } from '@/app/todos/actions/deleteTodo'

export function TodosList({ promise }: { promise: Promise<Todo[]> }) {
  const rows = use(promise)

  return (
    <div>
      {rows.map((row) => {
        return (
          <div key={row.id}>
            {row.text}

            <form action={deleteTodo}>
              <input type='hidden' name='id' value={row.id} />
              <button type='submit'>x</button>
            </form>
          </div>
        )
      })}
    </div>
  )
}

```

In a server action we get the `id` value from the FormData object:

```typescript
'use server'

import { sql } from '@vercel/postgres'
import { revalidatePath } from 'next/cache'

export async function deleteTodo(formData: FormData) {
  const id = formData.get('id') as unknown as number

  // mutate data
  await sql`DELETE FROM todos WHERE id = ${id}`

  // revalidate cache
  revalidatePath('/todos')
}
```

An alternative solution is to bind the id to the server action, using [bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).

First we modify the server action to accept an `id` parameter:

```typescript
'use server'

import { sql } from '@vercel/postgres'
import { revalidatePath } from 'next/cache'

export async function deleteTodo(id: number) {
  // mutate data
  await sql`DELETE FROM todos WHERE id = ${id}`

  // revalidate cache
  revalidatePath('/todos')
}

```

NOTE: if you _also_ need FormData, append that after that `id` parameter in the function parameters:

```typescript
//...

export async function deleteTodo(id: number, formData: FormData) {
  //...
}
```

Now before using the form action, call `bind()` to bind the `id` argument to it:

```typescript
'use client'

import { use } from 'react'
import type { Todo } from '@/app/types.ts'
import { deleteTodo } from '@/app/todos/actions/deleteTodo'

export function TodosList({ promise }: { promise: Promise<Todo[]> }) {
  const rows = use(promise)

  return (
    <div>
      {rows.map((row) => {
        const deleteTodoWithId = deleteTodo.bind(null, row.id)

        return (
          <div key={row.id}>
            {row.text}

            <form action={deleteTodoWithId}>
              <button type='submit'>x</button>
            </form>
          </div>)
      }
      ))}
    </div>
  )
}
```
