# another-redux-manager

> Yet another attempt to reduce boilerplate for async actions and reducers.

Latest version **4.0.0** (published 2019-10-23) · ISC license · 0 weekly downloads

## Install

```sh
npm install another-redux-manager
pnpm add another-redux-manager
yarn add another-redux-manager
bun add another-redux-manager
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 4.0.0 |
| Published | 2019-10-23 |
| First published | 2019-02-08 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 56.2 KB |
| Known vulnerabilities | 0 (+25 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 2 |
| Author | Dilshan de Silva |
| Maintainers | ddesilva80 |
| Keywords | react, context, eventbus |

## Links

- npm: https://www.npmjs.com/package/another-redux-manager
- Repository: https://github.com/ddesilva/another-redux-manager
- Homepage: https://github.com/ddesilva/another-redux-manager#readme
- Issues: https://github.com/ddesilva/another-redux-manager/issues
- npm.io page: https://npm.io/package/another-redux-manager

## Dependencies (2)

- [axios](https://npm.io/package/axios.md) ^0.19.0
- [axios-mock-adapter](https://npm.io/package/axios-mock-adapter.md) ^1.17.0

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 4.0.0 (latest) — 2019-10-23
- 3.1.1 — 2019-10-04
- 3.1.0 — 2019-10-03
- 3.0.1 — 2019-05-07
- 3.0.0 — 2019-05-06
- 2.0.3 — 2019-02-18
- 2.0.2 — 2019-02-14
- 2.0.1 — 2019-02-11
- 2.0.0 — 2019-02-08

## README

# Another Redux Manager
Yes yet another attempt to reduce boilerplate for redux whilst still keeping granular control over actions and reducers.

## Why
- Reduces boilerplate
- No overblown middleware required
- Less opinionated
- plays nice with existing codebase (use as much or as little as your want)
- More control over shape of your store and reducers

Dependencies
- axios

## Install
```js
$ npm i another-redux-manager axios
```

## Example

```js

import { createReduxManager } from 'another-redux-manager';

// create a redux manager instance
export const getContentManager = createReduxManager('GET_CONTENT');

// example redux thunk which dispatches actions
export function getContent() {
  return dispatch => {
    dispatch(getContentManager.inProgress());

    return getContentManager.fetch({url: '/some-endpoint'})
      .then(data => {
        return dispatch(getContentManager.success(data));
      })
      .catch(error => {
        return dispatch(getContentManager.failure(error));
      });
  };
}

// example reducer
const INITIAL_STATE = {
  [getContentManager.name]: {
      status: getContentManager.actionTypes.initial,
      error: null
      results: null
    },
};

function contentReducer(state = INITIAL_STATE, action) {
  switch (action.type) {
    case getContentManager.actionTypes.initial:
        return getContentManager.reducerMethods.initial(state, INITIAL_STATE[getContentManager.name].results);
    case getContentManager.actionTypes.inProgress:
        return getContentManager.reducerMethods.inProgress(state, action);
    case getContentManager.actionTypes.success:
      return getContentManager.reducerMethods.success(state, action);
    case getContentManager.actionTypes.failure:
      return getContentManager.reducerMethods.failure(state, action);
    default:
      return state;
  }
}

```



>NOTE: The default success reducer merges the results object with the data you fetch. If you require a full replace then use the advanced reducer configuration below.-


## Getting Started

```js
const contentReduxManager = createReduxManager({name: 'CONTENT'});
```

returns the following object:
```js
{
  name:'CONTENT',
  actionTypes:{
    initial:'CONTENT_FETCH_INITIAL',
    inProgress:'CONTENT_FETCH_IN_PROGRESS',
    success:'CONTENT_FETCH_SUCCESS',
    failure:'CONTENT_FETCH_FAILED'
  },
  actionTypeKeys:{
    CONTENT_FETCH_INITIAL:'CONTENT_FETCH_INITIAL',
    CONTENT_FETCH_IN_PROGRESS:'CONTENT_FETCH_IN_PROGRESS',
    CONTENT_FETCH_SUCCESS:'CONTENT_FETCH_SUCCESS',
    CONTENT_FETCH_FAILED:'CONTENT_FETCH_FAILED'
  },
  actions: {
    initial: () => {...},
    inProgress: () => {...},
    success: () => {...},
    faulure: () => {...},
  },
  reducerMethods:{
    initial: () => {...},
    inProgress: () => {...},
    success: () => {...},
    faulure: () => {...},
  },
  initial: () => {...},
  inProgress: () => {...},
  success: () => {...},
  faulure: () => {...},
}
```

Access ActionCreators
```js
const { initial, inProgress, success, failure} = contentReduxManager.actions;

or also available as shorthand references:

const { initial, inProgress, success, failure} = contentReduxManager;
```

Access Action types
```js
const { initial, inProgress, success, failure } = contentReduxManager.actionTypes;
const { CONTENT_FETCH_INITIAL, CONTENT_FETCH_IN_PROGRESS, CONTENT_FETCH_SUCCESS, CONTENT_FETCH_FAILED } = contentReduxManager.actionTypeKeys; // plain action types
```

Access Reducer Methods (for use in your switch statement in your reducer)
```js
const { initial, inProgress, success, failure} = contentReduxManager.reducerMethods; // reducer methods
```

You can also define multiple arguments to your actions (if you need to)
```js
const contentReduxManager = createReduxManager({name: 'CONTENT', resultsPropsName: 'results' }, 'payload', 'anotherProp');

console.log(actions.inProgress({payload: 'test', anotherProp: 'test' }));
// { type: 'CONTENT_FETCH_IN_PROGRESS', payload: 'test', anotherProp: 'test' }

```


## Usage

Create a redux helper
```js
const contentReduxManager = createReduxManager({name: 'CONTENT', argNames: ['payload'], resultsPropsName: 'results', reducerMethods: () => {} });
```

Properties:

| prop | desc  |
|---|---|
| name  | unique prefix for actions and reducers (RECOMMENDED: all uppercase and separated by underscore to match async postfixes)  |
| argNames  | array of argument names for actions (OPTIONAL: defaults to \['payload'\])  |
| resultsPropsName  | name of property in the reducer to place fetched data (OPTIONAL: defaults to \['results'\]) |
| reducerMethods  | function that allows customising of shape of reducer (OPTIONAL: see advanced usage) |

Call async http endpoint (axios)
```js
const result = await contentReduxManager.fetch({query: '/some-endpoint'});
```

| prop | desc  |
|---|---|
| type  | 'POST', 'DELETE', 'PUT', 'PATCH' .. defaults to 'GET' |
| logger  | your choice of logging util. Must implement logger.error() method. Defaults to console.error  |
| config  | axios config for post params, headers etc.. |
| name  | used when logging errors. outputs 'Fetch <name> Failed |


## Advanced Usage

by default the shape of each reducer method looks something like:
```js
const makeReducerMethods = (reduxManager, resultsPropName) => {
  return {
    initial: (state, initialData) => {
      return {
        ...state,
        ...{
          [reduxManager.name]: {
            ...{
              [resultsPropName]: initialData,
              status: reduxManager.actionTypes.initial,
              error: null
            }
          }
        }
      };
    },
    success: (state, action) => {
      return {
        ...state,
        ...{
          [reduxManager.name]: {
            ...{
              [resultsPropName]: { ...state[reduxManager.name][resultsPropName], ...action.payload },
              status: reduxManager.actionTypes.success,
              error: null
            }
          }
        }
      };
    },
    inProgress: state => {
      return {
        ...state,
        ...{
          [reduxManager.name]: {
            ...state[reduxManager.name],
            ...{
              status: reduxManager.actionTypes.inProgress,
              error: null
            }
          }
        }
      };
    },
    failure: (state, action) => {
      return {
        ...state,
        ...{
          [reduxManager.name]: {
            ...state[reduxManager.name],
            ...{
              status: reduxManager.actionTypes.failure,
              error: action.payload
            }
          }
        }
      };
    }
  };
};

export { makeReducerMethods };

```


However if you require custom shape for your state you can pass your own in as a property to the createReduxManager method

```js

const makeReducerMethods = (reduxManager, resultsPropName) => {
  return {
    success: (state, action) => {
      return {
        ...state,
        ...{
          [resultsPropName]: action.payload,
          [reduxManager.name]: {
            status: reduxManager.actionTypes.success,
            error: null
          }
        }
      };
    },
    inProgress: (state, action, initial) => {
      return {
        ...state,
        ...{
          [resultsPropName]: initial,
          [reduxManager.name]: {
            status: reduxManager.actionTypes.inProgress,
            error: null
          }
        }
      };
    },
    failure: (state, action, initial) => {
      return {
        ...state,
        ...{
          [resultsPropName]: initial,
          [reduxManager.name]: {
            status: reduxManager.actionTypes.failure,
            error: action.payload
          }
        }
      };
    }
  };
};


export const getContentReduxManager = createReduxManager({
  name: 'GET_CONTENT',
  reducerMethods: makeReducerMethods
});

```



You can also create a single action creator
```js
import { makeActionCreator } from 'another-redux-manager';

const inProgress = makeActionCreator('GET_CONTENT_IN_PROGRESS', 'payload');
```

---
_Source: https://npm.io/package/another-redux-manager · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
