[🏠 Home](../README.md) # Dynadux - Middlewares ## About With middlewares, you can - prepare, maintain, decorate, clean up the state before or after action's dispatch - create 3rd party middleware libraries, like, load the weather for a city, etc - debugging, monitor the state - dispatch other 'parallel' actions - send usage stats Middlewares can - access the entire state - access all dispatched actions from anywhere - dispatch actions - have their actions and behave as a 3rd party libraries ## Write your middleware as 3rd party Middlewares in Dynadux can `dispatch` anything out of the box, without additional Thunk middlewares as Redux needs. You can write your middlewares that it is only a function that returns an `IDynaduxMiddleware`. The user of the middleware will have to load only the middleware function in Dynadux's `middlewares` array prop only without the need to register reducers _like in Redux_! # API The interface of what the middleware is: ``` interface IDynaduxMiddleware { init?: (store: Dynadux) => void; before?: (reducerAPI: IDynaduxMiddlewareBeforeAPI) => undefined | void | Partial; after?: (reducerAPI: IDynaduxMiddlewareAfterAPI) => undefined | void | Partial; } ``` Technically the middleware is an object of the above `init`, `before` and `after` callbacks. All of them are optional. Below are the interfaces of the `before` and `after` callbacks. They are the same as the Reducers callbacks! The only difference is the `after` callback has the `initialState` prop where is the version of the state before the dispatch of the action. ``` interface IDynaduxMiddlewareBeforeAPI { action: string; payload: any; dispatch: TDynaduxMiddlewareDispatch; state: TState; } interface IDynaduxMiddlewareAfterAPI { action: string; payload: any; reducerElapsedMs: number; dispatch: TDynaduxMiddlewareDispatch; state: TState; changed: boolean;* initialState: TState; } type TDynaduxDispatch = (action: string, payload: TPayload) => void; ``` **Note!** The `changed` indicates if the state is changed by the Middlewares and Reducer so far! The state might be changed by the rest loaded Middlewares. ## Implementing a middleware On Store's initialization, the middleware gets the reference of the Store, so it has access to the initial state and the `dispatch` method. This is done through the `init` callback property. The middleware is acting before the dispatch of the action and/or after the dispatch of the action. On `before`, you can prepare the state, or enrich the payload. On `after`, _the most useful one_, you can react to the dispatched action. On `after`, you have the `initialState` additionally, and you can compare what the action's reducer did. The implementation of each phase may return a partial state or nothing for no state changes. In both phases, you can access the - `action` (string) - `payload` - `state` (the entire state) - `dispatch` method The `initialState` is offered on `after` only. This API is the same as the reducers. So, middlewares act like reducers. > Redux doesn’t have the `before` phase. ## Sub-Stores Since the creation of the Store with Dynadux is super easy, complex middlewares would have their Store. These are called Sub-Stores and have no relation with other stores. Middleware's Sub-Store eventually will update a part of the Parent Store where they added. Technically on Sub-Store's `onChange`, it will `dispatch` on the parent Store. # Examples #### Logger This middleware consoles the action that has dispatched. ``` middlewares: [ { after: ({action, payload}) => { console.log('dispatch', new Date, action, payload); }, } ], ``` #### Send stats ``` middlewares: [ { after: ({action, payload}) => { If (action === ‘USER-LOGIN-ERROR) { // post here there error, async } }, } ], ``` #### Debugging middleware Are you going to collect the dispatched actions for debugging? Well, it is already ready! Dynadux shipped with a small middleware for debugging. For how to use it read next chapter [Debugging](./API-Debugging.md) Curious, how is implemented? Check it [here](https://github.com/aneldev/dynadux/blob/master/src/middlewares/dynaduxDebugMiddleware.ts). #### Dynadux History Middleware Middlewares can have their actions. A live example is the [dynadux-history-middleware](https://github.com/aneldev/dynadux-history-middleware). The full implementation is in [this file](https://github.com/aneldev/dynadux-history-middleware/blob/master/src/dynaduxHistoryMiddleware.ts). Here, it is easy to make a History State management, navigating back and forth in time and offering **restore points**! # Continue [⬅️ Reducers](../README.md) 🔶 [Sections ➡️](./API-Sections.md) [🏠 Home, Contents](../README.md#table-of-contents)