# Muffin Dev for Node - App Framework - Hooks

The hooks system allows you to listen for any event triggered by a service, and react to it synchronously or asynchronously.

Hooks are handled by a `HooksManager` instance. This class can host several hooks, but they all belong to one `Application`, `Service` or custom class instance.

Hooks managers have two types of interactions:

- Hooks: a list of callbacks that can be ordered, and are called one after the other in that order. It takes account of `async` methods, and will wait for a callback to end its execution before executing the next one
- Events: when a hook is executed in a hooks manager, it will trigger an event of the same name of the hook. Unlike a hook, events doesn't take account of `async` methods, and all the listeners will be executed at the same time

## Create a `HooksManager`

Use `HooksManager.create()` to register a hook, and call `HooksManager.exec()` when you want to execute it. As an exemple, here is how to create and execute a hook in a custom service:

```ts
import { HooksManager, IService } from '@muffin-dev/app-framework';

export class CustomService implements IService {
    public hooks = new HooksManager<CustomService>();

    public init(name: string, app: Application) {
        // The create() method
        this.hooks.create('beforeDoingSomething');
        this.hooks.create('afterDoingSomething');
    }

    public async doSomething(data: any) {
        await this.hooks.exec('beforeDoingSomething');
        /* ... */
        await this.hooks.exec('afterDoingSomething');
    }
}
```

This way, any user of the `CustomService` can add a callback or an event listener to the hooks manager of this service.

## Listen to a hook

Use `HooksManager.add()` to add a callback for a hook, or `HooksManager.on()` to add an event listener. Note that you can define an order for a hook callback. The lowest the value, the first the callback is executed. Based on the example of the previous section, here is an example of adding callbacks and listeners:

```ts
import { IHookContext } from '@muffin-dev/app-framework';
import { CustomService } from '/path/to/service';

const customService = new CustomService();
customService.init(null, null);

customService.add('beforeDoingSomething', (context: IHookContext) => {
    console.log('beforeDoingSomething hook first callback');
});

customService.add('beforeDoingSomething', (context: IHookContext) => {
    console.log('beforeDoingSomething hook second callback');
}, 10);

customService.add('afterDoingSomething', async (context: IHookContext) => {
    console.log('afterDoingSomething hook callback');
});

// Adds an event listener for "beforeDoingSomething" hook. Note that even for event listener, the hook context object is passed.
customService.on('beforeDoingSomething', (context: IHookContext) => {
    console.log('beforeDoingSomething event triggered');
})
```