# Action

Actions are meant to represent unique reactive events. Action is an RxJS [Subject](https://rxjs.dev/guide/subject) like construct.\
Actions don't replay the last value when subscribed to, unlike [Units](https://docs.activejs.dev/activejs/fundamentals/units), [Systems](https://docs.activejs.dev/activejs/fundamentals/systems) and [Clusters](https://docs.activejs.dev/activejs/fundamentals/cluster).\
Actions help trigger customized operations in a reactive fashion.

You can call an Action a simplified form of a Unit as they share the same base API, although configured in a slightly different way.

* It has a `dispatch` method, just like a [Unit](https://docs.activejs.dev/activejs/fundamentals/units).

* It extends the RxJS Observable class, hence it's an Observable.

* By default, It doesn't replay when subscribed to, unlike a Unit.

* It doesn't require an initial value, yet provides direct access to the last emitted value, just like a Unit.

* It can only cache one value at a time, unlike a Unit.

* Unlike Units, it doesn't perform any checks on `dispatch`.

See [API reference](https://api.activejs.dev/classes/action) for more details.

### Initializing an Action:

```typescript
// create an Action, that accepts number as its value
const multiplyAction = new Action<number>();
```

Action is an Observable but not a Subject.

```typescript
multiplyAction instanceof Subject // false 
multiplyAction instanceof Observable // true
```

### Accessing the value:

```typescript
// access the value
console.log(multiplyAction.value()) // logs undefined

// dynamically access the value
multiplyAction.subscribe(value => {
  console.log(value) // will log future values
  // do something with the value here
});
```

### Dispatching a value:

```typescript
// dispatch a value
multiplyAction.dispatch(3);

// replay the value
multiplyAction.replay(); // multiplyAction emits 3 again
```

The above example shows the basic usage of an Action, it's similar to an RxJS Subject with slight differences.

### Creating a stream:

The real-life usage would most probably be to create streams using the Action.

```typescript
// create a NumUnit to apply the multiplyAction on it
const numUnit = new NumUnit({initialValue: 10})


// create a stream using the earlier Action and above Unit
const subscription = multiplyAction.pipe(
  tap(multiplier => {
    // multiply the numUnit's value and update it
    numUnit.dispatch(currValue => currValue * multiplier)
  })
).subscribe();


// or simply use the built-in createStream method
const stream = multiplyAction.createStream(action$ => {
  return action$.pipe(
    tap(multiplier => {
      // multiply the numUnit's value and update it
      numUnit.dispatch(currValue => currValue * multiplier)
    })
  )
})
```

The advantage of using the `createStream` method is that we get a [Stream](https://docs.activejs.dev/activejs/utilities/stream) instance.\
So we can stop and re-start the multiplication stream.

```typescript
// stop the multiplication stream
stream.unsubscribe();

// re-start the multiplication stream
stream.resubscribe();
```

## Action vs Units vs BehaviorSubject

|                                                                                                        | Action | Unit | BehaviorSubject |
| ------------------------------------------------------------------------------------------------------ | ------ | ---- | --------------- |
| Replays value on subscription (by default)                                                             | ❌      | ✅    | ✅               |
| Can be configured to replay value on subscription                                                      | ✅      | ✅    | ❌               |
| <p>Allows to listen to only future values</p><p>(useful when configured to replay on subscription)</p> | ✅      | ✅    | ❌               |
| Accepts an initial-value                                                                               | ✅      | ✅    | ✅               |
| Can cache more than one value                                                                          | ❌      | ✅    | ❌               |
| Validates dispatched values                                                                            | ❌      | ✅    | ❌               |
| Can re-emit/replay last value manually                                                                 | ✅      | ✅    | ❌               |
| Can be part of a [Cluster](https://docs.activejs.dev/activejs/fundamentals/cluster)                    | ✅      | ✅    | ❌               |

## Configuration Options

The configuration options can be passed at the time of instantiation. All the configuration options are optional. Some options can also be set globally. See [Configuration](https://docs.activejs.dev/activejs/guides/configuration) for more details.


---

# 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.activejs.dev/activejs/fundamentals/action.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.
