# Methods

In short words, methods created a way to compose actions in one function. But it is much more flexible. It's possible to create async function, and even use a rxjs helper. And is able to get another module's action/state.

```typescript
module
  .actions({
    ...
  })
  .methods(({ getActions }) => ({
    complexMutation: () => {
      getActions()...
      getActions()...
    }
  }))
```



### Async functions

```typescript
module.methods(({ getActions }) => ({
  addAfter: async () => {
    await ...
    getActions()...
  }
}))
```



### RxJS

```tsx
import { effect } from 'zoov/effect';
import { defineModule } from 'zoov';
import { exhaustMap, tap } from 'rxjs/operators';

const CounterModule = defineModule({ count: 0 })
  .actions({
    add: (draft) => draft.count++,
  })
  .methods(({ getActions }) => ({
    addAfter: effect<number>((payload$) =>
      payload$.pipe(
        exhaustMap((timeout) => {
          return timer(timeout).pipe(tap(() => getActions().add()));
        })
      )
    ),
  }))
  .build();

```



### Context related

Here, getActions, getState (the perform handler), can always get the correct module instance of another module even in the nested action function, depending on where you use the method.

```typescript
module.methods(({ getActions, getState }) => ({
  addOne: () => {
    console.log(getState(AnotherModule));
    getActions(LogModule).log();
  },
}))
```
