# Scope and context

{% hint style="success" %}
This is the official documentation of the `@forestadmin/agent` Node.js agent.
{% endhint %}

Actions can have 3 different scopes: `Single`, `Bulk`, and `Global`.

The scope of an action defines how it can be triggered and which records it will target.

| -                                                          | Single                           | Bulk                                                   | Global                                                      |
| ---------------------------------------------------------- | -------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------- |
| **Targeted records**                                       | One at a time                    | All selected and matching the current segment / search | Your choice among all matching the current segment / search |
| **Can be triggered from the List View**                    | When a single record is selected | When one or more records are selected                  | ✅                                                           |
| **Can be triggered from the Details View or Summary View** | ✅                                | ✅                                                      | 🚫                                                          |

## The `context` object

The `context` object is central to writing Actions controllers in Forest Admin.

It is the bridge between all the data that your agent has access to and the action's execution. It is passed to the `execute` function as the first argument and provides access to the following properties:

* `getRecord(fieldNames)` (or `getRecords(fieldNames)` for `Bulk` and `Global` Actions)
* `getRecordId()` (or `getRecordIds()` for `Bulk` and `Global` Actions)
* `collection` the collection on which the action is declared, which can be queried using the [Forest Admin Query Interface](https://docs.forestadmin.com/developer-guide-agents-nodejs/data-sources/getting-started/queries#collection-interface).
* `dataSource` the composite data source who contains all your collections, which can be queried using the [Forest Admin Query Interface](https://docs.forestadmin.com/developer-guide-agents-nodejs/data-sources/getting-started/queries#data-source-interface)
* `filter` a filter that can be used to query the collection, and which is based on action scope and the list of selected records.
* `caller` an object containing information about the user who is performing the action (see details below)
* `hasFieldChanged(fieldName)` the name of the field who has changed in the UI. [See an example of usage](https://docs.forestadmin.com/developer-guide-agents-nodejs/agent-customization/forms-dynamic#example-4-using-hasfieldchanged-to-reset-value)

{% hint style="warning" %}
`changedField` was deprecated in favor of `hasFieldChanged(fieldName)` starting from `@forestadmin/agent@1.28.3` see more information in [this issue report](https://github.com/ForestAdmin/agent-nodejs/issues/815).
{% endhint %}

### The `caller` object

The `caller` object contains information about the current user performing the action:

| Property    | Description                   |
| ----------- | ----------------------------- |
| `id`        | User ID                       |
| `email`     | User email                    |
| `firstName` | First name                    |
| `lastName`  | Last name                     |
| `team`      | Team name                     |
| `role`      | Role name                     |
| `tags`      | Custom tags (key-value pairs) |
| `timezone`  | User timezone                 |

### Error methods

The context also provides methods to throw errors that will be displayed in the Forest Admin UI:

| Method                          | Description                |
| ------------------------------- | -------------------------- |
| `throwValidationError(message)` | Display a validation error |
| `throwForbiddenError(message)`  | Display a forbidden error  |
| `throwError(message)`           | Display a generic error    |

### Example 1: Getting data from the selected records

We can simply use the `getRecord(fieldNames)` method to get any column from the selected record or a relation.

```javascript
agent.customizeCollection('customers', collection =>
  collection.addAction('Call me John in the server logs', {
    scope: 'Single',
    execute: async context => {
      // use getRecords() for Bulk and Global Actions
      const { firstName } = await context.getRecord(['firstName']);

      if (firstName === 'John') {
        console.log('Hi John!');
      } else {
        console.error('You are not John!');
      }
    },
  }),
);
```

### Example 2: Updating a field of the selected record

For simple queries, use `context.collection` and `context.filter` to query the collection.

Those are instances of objects from the [Forest Admin Query Interface](https://docs.forestadmin.com/developer-guide-agents-nodejs/data-sources/getting-started).

```javascript
agent.customizeCollection('companies', collection =>
  collection.addAction('Mark as live', {
    scope: 'Single',
    execute: async context => {
      await context.collection.update(context.filter, { live: true });
    },
  }),
);
```

### Example 3: Coding any business logic

Forest Admin does not impose any restriction on the handler: you are free to write the `execute` handler to fit your use case.

You are free to call external APIs, query your database, or perform any work in action handlers.

```javascript
import axios from 'axios';

agent.customizeCollection('companies', collection =>
  collection.addAction('Mark as live', {
    scope: 'Single',
    execute: async context => {
      const url = 'http://my-api.com/mark-as-live';
      const params = { id: await context.getRecordId() };

      await axios.post(url, params);
    },
  }),
);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestadmin.com/developer-guide-agents-nodejs/agent-customization/actions/scope-context.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
