# Action

Action is another type of Interceptor. Unlike Filter, Action can accept multiple parameters and it only returns either an empty `Promise.resolve()` or a `Promise.reject(ex)` with an error.

## Creating Action

Similar to Filter, you can create action by either declaring an Action class or calling `actionManager.create()`.

### Declaring Action Class

Action class must expose a function named `do` . This function will be invoked whenever the action gets performed.

Following example demonstrates a LoggingAction that writes log to console when price calculation completed:

```javascript
class LoggingAction {

    async do(original, discount, tax) {
        console.log(`Calculation completed. Original: ${original}, Discount: ${discount}, Tax: ${tax}`);
    }
}
```

or:

```javascript
function LoggingAction() {

    this.do = function(original, discount, tax) {
        console.log(`Calculation completed. Original: ${original}, Discount: ${discount}, Tax: ${tax}`);
        return Promise.resolve();    
    }
}
```

### Creating Action via Action Manager

A better way to create action is to use Action Manager. Its usage is similar to Filter Manager:

```javascript
var action = actionManager.create(async (original, discount, tax) => {
    console.log(`Calculation completed. Original: ${original}, Discount: ${discount}, Tax: ${tax}`);
});
```

or:

```javascript
var action = actionManager.create((original, discount, tax) => {
    console.log(`Calculation completed. Original: ${original}, Discount: ${discount}, Tax: ${tax}`);
    return Promise.resolve();
});
```

## Creating Action Manager

Action Manager centralize action registration and provides a method to invoke actions. To create a new Action Manager:

```javascript
const { action } = require('robo-toolkit');
// or
const _a = require('robo-toolkit').action;

const actionManager= _a.createManager();
```

Note that `_a` is already a static global instance of Action Manager.

## Registering Action

To register an action to Action Manager:

```javascript
actionManager.add(name, action, priority);
```

In which:

* `name` is name of the action. Multiple actions with the same name will be chained.&#x20;
* `action` is the action created using methods mentioned in previous section.
* `priority` is a number indicating priority of the action in the chain. The lower number, the higher priority. The higher prioritized action will be invoked prior to the lower ones. Default is zero.

Let's register our LoggingAction to the global Action Manager:

```javascript
_a.add('after-calculate-price', new LoggingAction());
```

or:

```javascript
_a.add('after-calculate-price', _a.create(async (original, discount, tax) => {
    console.log(`Calculation completed. Original: \$${original}, Discount: ${discount}%, Tax: ${tax}%`);
}));
```

## Invoking Action

To invoke a specified action, call `do` on Action Manager:

```javascript
await actionManager.do(name, ...args);
```

Following example invokes the `after-calculate-price` action:

```javascript
await _a.do('after-calculate-price', 100, 10, 5);
```

Output console will look like:

```
Calculation completed. Original: $100, Discount: 10%, Tax: 5%
```
