Simple library for creating schema-validated Redux Actions (or thunks, promises, etc.). Powered by the awesomely awesome Schema-Inspector.
npm install redux-action-factory --save
In big projects, many action types have to be managed, each one with its Action Creator (sometimes a thunk that will dispatch other actions and perform side-effects), and that generates a large number of files, complexity, and makes the project harder to maintain in general.
With Redux Action Factory, good maintenance is achieved by:
- Centralizing the Actions' specification in a file.
- Ensuring robustness in the action creation process by checking arguments' types.
- Eliminating the need for synchronous actions' Action Creators.
- Providing a common interface and place for all complex Action Creators (asynchronous action creators, thunks, etc.).
Furthermore, it has been designed with Unit Testing in mind.
In your index.js you should put something similar to:
index.js:
var initialize = require('redux-action-factory').initialize;
var actionsSpecification = require('./actions.json');
initialize({
actions: actionsSpecification,
actionCreators: [...], // optional
inject: [...] // optional
});
Note: It has been made to support ES6 imports:
import {initialize} from 'redux-action-factory';
Example of actions.json:
{
"ACTION_NAME": {
"type": "myProject/ACTION",
"args": {
"type": "object",
"strict": true,
"properties": {
"actionParam1": {"type": "number"},
"actionParam2": {"type": "string", "optional": true}
}
}
}
}
Somewhere in your app:
var createAction = require('redux-action-factory').createAction;
dispatch(createAction('ACTION_NAME', {actionParam1: 42, actionParam2: 'Other data'}));
In your reducers, instead of:
case 'ACTION_NAME':
Just do:
var type = require('redux-action-factory').type;
[...]
case type('ACTION_NAME'):
When testing, if you need to check if the proper action was created but you don't want to trigger any side effects or execute any Action Creator code, you can use the createRawAction
method as follows:
var createRawAction = require('redux-action-factory').createRawAction;
// This won't execute the Action Creator function
createRawAction('ACTION_NAME', {actionParam1: 42, actionParam2: 'Other data'});
Also, if you need to test the correctness of your actions.json
file(s), you can use the exported objects actionsSanitizationSchema
and actionsValidationSchema
like this:
var sanitization = require('redux-action-factory').actionsSanitizationSchema;
var validation = require('redux-action-factory').actionsValidationSchema;
var inspector = require('schema-inspector'); // Schema-Inspector should be installed in your project
var actions = require('./actions.json');
var assert = require('chai').assert;
describe('Actions Schema', function () {
it('should be a valid schema', function () {
inspector.sanitize(sanitization, actions);
var result = inspector.validate(validation, actions);
assert.ok(result.valid, result.format());
});
});
initialize(configuration)
Creates and initializes the Action Factory every time it is called. Only the last call will be taken into account.
configuration
: The configuration object for the factory. It allows the following properties:actions
: An actions specification object. Check Actions API for more details.actionCreators
(optional): A map of Action Creators names and functions. These functions should return dispatchable objects in your Redux system. A good practice is to define each of them in a separate file inside a specific folder, and then require them all with a glob require library (babel-plugin-import-glob, node-glob, etc.).inject
(optional): An additional parameter that will be injected as a second parameter into every Action Creator call. Any type allowed, also objects that can contain whatever fits you. Useful for passing interfaces for actions side-effects (like APIs interfaces) into every action creator.
{
"ACTION": {
"type": {string}
"args": {object}
"sanitize": {object} //optional
"creator": {string} //optional
}
}
type
: A unique string that shall be used to identify the Action in the reducers and across systems (recommended to be namespaced).args
: A valid Schema-Inspector's validation schema to run against the parameters passed increateAction
.sanitize
(optional): A valid Schema-Inspector's sanitization schema to run against the parameters passed increateAction
.creator
(optional): The name of an Action Creator provided in the initial configuration.
getConfig()
Returns the config passed in the last call to initialize
.
createAction(actionName, params)
If actionName and params are compliant with the configuration's actions specification, creates and returns a dispatchable action. Otherwise, throws an Error with human readable details on the failure.
actionName
: The Action's name in the specification.params
(optional): The Action's data.
If no Action Creator was defined for that action, returns the raw action, an object such as:
{
type: configuration.actions[actionName].type,
...params
}
Otherwise, executes the provided action creator with the raw action as a first parameter and the injected parameter as second.
actionCreator(rawAction, configuration.inject)
createRawAction(actionName, params)
Same as createAction
, but it always returns the raw action object without calling the actionCreator (if there was one).
actionsValidationSchema
The schema against which the configuration.actions
object will be validated after being sanitized.
Useful for validating actions.json
correctness at testing time.
actionsSanitizationSchema
The schema by which the configuration.actions
object will be sanitized before validation.
Useful for validating actions.json
correctness at testing time.
Thanks to the boilerplate's authors Travelport-Ukraine for npm-module-boilerplate-es6.
If you have an idea on how to improve this library, I listen to suggestions here in the issues channel.