# UpdatePromise

UpdatePromise provides chainable methods for configuring UPDATE operations.

The `UpdatePromise` class provides a chainable interface for configuring UPDATE operations before execution. It extends `Promise`, allowing you to `await` it directly or chain configuration methods.

**Returned by:** [`SurrealQueryable.update()`](/docs/reference/javascript/api/core/surreal-queryable.md#update)

**Source:** [query/update.ts](https://github.com/surrealdb/surrealdb.js/blob/main/packages/sdk/src/query/update.ts)

## Type parameters

- `T` - The result type
- `I` - The input type for record data
- `J` - Boolean indicating if result is JSON (default: `false`)

## Configuration methods

### `.content()` {#content}

Replace the entire record content with new data.

```ts title="Method Syntax"
updatePromise.content(data)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>data</code> <label label="required" /></td>
            <td><code>Values&lt;I&gt;</code></td>
            <td>Complete replacement data (excluding id field).</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Example

```ts
const user = await db.update(new RecordId('users', 'john'))
    .content({
        name: 'John Smith',
        email: 'john.smith@example.com',
        age: 31
    });
// Replaces all fields
```

---

### `.merge()` {#merge}

Merge partial updates into the existing record.

```ts title="Method Syntax"
updatePromise.merge(data)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>data</code> <label label="required" /></td>
            <td><code>Values&lt;I&gt;</code></td>
            <td>Partial data to merge (only specified fields are updated).</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Examples

```ts title="Update Single Field"
const user = await db.update(new RecordId('users', 'john'))
    .merge({ email: 'newemail@example.com' });
// Only updates email, other fields unchanged
```

```ts title="Update Multiple Fields"
const user = await db.update(new RecordId('users', 'john'))
    .merge({
        email: 'new@example.com',
        age: 31,
        updated_at: DateTime.now()
    });
```

---

### `.replace()` {#replace}

Replace specific fields while keeping others unchanged.

```ts title="Method Syntax"
updatePromise.replace(data)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>data</code> <label label="required" /></td>
            <td><code>Values&lt;I&gt;</code></td>
            <td>Fields to replace.</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Example

```ts
const user = await db.update(new RecordId('users', 'john'))
    .replace({ status: 'inactive' });
```

---

### `.patch()` {#patch}

Apply JSON Patch operations to update the record.

```ts title="Method Syntax"
updatePromise.patch(operations)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>operations</code> <label label="required" /></td>
            <td><code>Values&lt;I&gt;</code></td>
            <td>JSON Patch operations to apply.</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Example

```ts
const user = await db.update(new RecordId('users', 'john'))
    .patch([
        { op: 'replace', path: '/email', value: 'new@example.com' },
        { op: 'add', path: '/tags/-', value: 'premium' }
    ]);
```

---

### `.where()` {#where}

Add a WHERE clause to conditionally update records.

```ts title="Method Syntax"
updatePromise.where(expr)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>expr</code> <label label="required" /></td>
            <td><code>ExprLike</code></td>
            <td>The condition expression (string or <a href="/docs/reference/javascript/api/utilities/expr.md">Expression</a> object).</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Examples

```ts title="Conditional Update"
const users = await db.update(new Table('users'))
    .merge({ verified: true })
    .where('email_confirmed = true');
```

```ts title="With Expression Builder"
import { expr } from 'surrealdb';

const users = await db.update(new Table('users'))
    .merge({ status: 'inactive' })
    .where(expr(({ lt, field }) => 
        lt(field('last_login'), DateTime.parse('2024-01-01'))
    ));
```

---

### `.output()` {#output}

Specify what to return from the update operation.

```ts title="Method Syntax"
updatePromise.output(fields)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>fields</code> <label label="required" /></td>
            <td><code>Output</code></td>
            <td><code>"NONE"</code>, <code>"BEFORE"</code>, <code>"AFTER"</code>, <code>"DIFF"</code>, or field list.</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Examples

```ts title="Return Updated Record"
const user = await db.update(new RecordId('users', 'john'))
    .merge({ email: 'new@example.com' })
    .output('AFTER');
// Returns the record after update
```

```ts title="Return Only Changed Fields"
const diff = await db.update(new RecordId('users', 'john'))
    .merge({ email: 'new@example.com' })
    .output('DIFF');
// Returns only the changed fields
```

```ts title="Return Original Record"
const original = await db.update(new RecordId('users', 'john'))
    .merge({ email: 'new@example.com' })
    .output('BEFORE');
// Returns the record before update
```

---

### `.timeout()` {#timeout}

Set a timeout for the operation.

```ts title="Method Syntax"
updatePromise.timeout(duration)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>duration</code> <label label="required" /></td>
            <td><code><a href="/docs/reference/javascript/api/values/duration.md">Duration</a></code></td>
            <td>Maximum time to wait.</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

---

### `.retry()` {#retry}

Retry the operation with exponential backoff if it fails due to a write conflict. Off by default; passing an options object (or calling with no arguments) opts the operation in.

This overrides the connection-wide default set via the [`retry`](/docs/reference/javascript/api/types/#connectoptions) option on `ConnectOptions`.

```ts title="Method Syntax"
updatePromise.retry(options?)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>options</code> <label label="optional" /></td>
            <td><code>Partial&lt;<a href="/docs/reference/javascript/api/types/#retryoptions">RetryOptions</a>&gt;</code></td>
            <td>Retry configuration. If omitted, retry is enabled with the default configuration.</td>
        </tr>
    </tbody>
</table>

#### Returns
`UpdatePromise<T, I, J>` - Chainable promise

#### Example

```ts
await db.update(new RecordId('counter', 'c'))
    .merge({ n: 1 })
    .retry({ attempts: 3 });
```

---

### `.json()` {#json}

Return result as JSON string.

```ts title="Method Syntax"
updatePromise.json()
```

#### Returns
`UpdatePromise<T, I, true>` - Promise returning JSON string

---

### `.compile()` {#compile}

Compile the query into a `BoundQuery` without executing it.

```ts title="Method Syntax"
updatePromise.compile()
```

#### Returns
`BoundQuery<[T]>` - The compiled query

#### Example

```ts
const query = db.update(new Table('users'))
    .merge({ status: 'active' })
    .where('verified = true')
    .compile();
```

---

### `.stream()` {#stream}

Stream results as they arrive.

```ts title="Method Syntax"
updatePromise.stream()
```

#### Returns
`AsyncIterableIterator` - Async iterator

## Complete examples

### Basic updates

```ts
import { Surreal, RecordId, Table } from 'surrealdb';

const db = new Surreal();
await db.connect('ws://localhost:8000');

// Update single record with merge
const user = await db.update(new RecordId('users', 'john'))
    .merge({ email: 'john.new@example.com' });

// Replace entire record content
const user = await db.update(new RecordId('users', 'john'))
    .content({
        name: 'John Doe',
        email: 'john@example.com',
        age: 30,
        role: 'admin'
    });
```

### Bulk updates

```ts
// Update all users matching condition
const updated = await db.update(new Table('users'))
    .merge({ verified: true })
    .where('email_confirmed = true');

console.log(`Updated ${updated.length} users`);
```

### Conditional updates

```ts
// Update only if condition is met
const users = await db.update(new Table('users'))
    .merge({ status: 'inactive' })
    .where('last_login < $date', { 
        date: DateTime.parse('2024-01-01') 
    });
```

### Complex merge

```ts
const user = await db.update(new RecordId('users', 'john'))
    .merge({
        profile: {
            bio: 'Updated bio',
            avatar: 'new-avatar.jpg'
        },
        settings: {
            notifications: true,
            theme: 'dark'
        },
        updated_at: DateTime.now()
    });
```

### Tracking changes

```ts
const diff = await db.update(new RecordId('users', 'john'))
    .merge({ 
        email: 'new@example.com',
        age: 31 
    })
    .output('DIFF');

console.log('Changed fields:', diff);
// { email: 'new@example.com', age: 31 }
```

### Batch update with stream

```ts
const updates = db.update(new Table('users'))
    .merge({ last_check: DateTime.now() })
    .where('active = true');

for await (const user of updates.stream()) {
    console.log(`Updated user: ${user.id}`);
}
```

## Difference between methods

### `.content()` vs `.merge()` vs `.replace()`

```ts
// CONTENT: Replaces entire record
await db.update(recordId).content({
    name: 'John',
    email: 'john@example.com'
});
// Result: ONLY name and email exist, all other fields removed

// MERGE: Updates specified fields only
await db.update(recordId).merge({
    email: 'john@example.com'
});
// Result: Only email updated, all other fields preserved

// REPLACE: Similar to merge but with different semantics
await db.update(recordId).replace({
    email: 'john@example.com'
});
// Result: Replaces specified fields
```

## Chaining pattern

```ts
const result = await db.update(new Table('users'))
    .merge({ status: 'active' })
    .where('verified = true')
    .output('AFTER')
    .timeout(Duration.parse('5s'));
```

## See also

- [SurrealQueryable.update()](/docs/reference/javascript/api/core/surreal-queryable.md#update) - Method that returns UpdatePromise
- [UpsertPromise](/docs/reference/javascript/api/queries/upsert-promise.md) - Insert or update
- [CreatePromise](/docs/reference/javascript/api/queries/create-promise.md) - Create records
- [Query overview](/docs/reference/javascript/api/queries/) - All query builder classes
