Middlewares and Reducers for Redux
Motivation
Once you're required to fetch data from the server in your Redux applications, you need to either write a custom Middleware or use redux-* modules to fetch data. Anyway you need to implement actions creators, reducers or both. If your server provides rest api for data manipulation the implementation of anything becomes boring very quickly. And Redux-redents to the rescue!!!
The module contains the implementation of the:
- Promise middleware, supports fetching from and pulling to server data
- Chain middleware, supports call chains for chaining you actions.
- Dictionary reducers, provide convention based reducers to reduce server responses
You don't need to implement actions, just add reducers to the rootreducer and add middlewares to the store
Installation
npm install redux-redents
Quick sample
//file index.js//imports;;;;; //specify entitiesconst plants = fruit: {} vegetable: {}const EntConfig = defaults : baseUrl : 'http://server/uri' entities : plants //create reducersconst dicts = ;//create storeconst store = createStoredicts; ><Plants/></Provider>document); //file plants.js static propTypes = plants: propTypesarrayisRequired plant: propTypesobjectisRequired { thispropsactions; //load fruits list thispropsactions; //load an apple } return <div> <ul> thispropsplants //display list of the plants </ul> <h3>thispropsplantname</h3>//diplay selected plant <div> ; //connect props and actions to the Component { return plants: statefruits //connect fruits reducer to the plants property plant: statefruit ;} { return actions: //binds actions.entOper to the call of the entityOperation function ;} mapStateToProps mapDispatchToPropsGenTransactionsPage;
Full sample is available in the client-demo folder
Conventions and defaults
Redux-redents uses Entities object to get information about entities names, operations supported and their data.
Entities configuration by conventions
Entities type structure:
entities = defaults: baseUrl: //default baseUrl of the server endpoint entities : entityName : operation1: url: //operation url, {return request object} //- function to produce request to perform operation1
Default operations supported are:
- index - fetches the arrays of Entities.
- By convention uses the url
entities.defaults.baseUrl+"/"+entityName+"s"
- By convention uses the get method
- By convention uses the url
- get - fetches one entity
- By convention uses the url
entities.defaults.baseUrl+"/"+entityName+"s"+"/"+data
data is passed from the client code - By convention uses the get method
- By convention uses the url
- post - saves the entity data to the server
- By convention uses the url
entities.defaults.baseUrl+"/"+entityName+"s"
- By convention uses the post method
- By convention passes the data as the json body
- By convention uses the url
- delete - removes the entity from the server
- By convention uses the url
entities.defaults.baseUrl+"/"+entityName+"s"
- By convention uses the delete method
- By convention uses the url
You can override an operation and inside the operation you could override either the url, or the request. The request field of the entity object should be the function:
{ return promise}
It accepts data from the client code and returns promise that returns the result
Reducers by default
Redux-redents has the function that accepts Entities configuration and generates reducers for index and get operations for each entity mentioned in the configuration.
produces , //get ent1 ent1s : function(state,action), //index ent1 ent2 : function(state,action), //get ent2 ent2s : function(state,action), //index ent2}
Actions creator for promises
To emit actions that will fetch data from the server Redux-redents contains the entityOperation function
javascript function entityOperation(entity,operation,data,chainlink)
- entity - entity name to operate on
- operation - operation name to perform
- data - optional data required for operations. By convention data is used for
- 'get' - will be added to the url as
url/id
- 'post' - will be sent as request body
- 'delete' - will be added to the url as
url/id
- 'get' - will be added to the url as
- chainlink - optional action to perform after the current action will be finished. Action is the function that accepts the current action.res or whole action if its .res field is not defined
Promise Middleware
Promise Middleware accepts actions with promise dispatches original action with modified type (type+'_REQUEST') and adds promise callbacks that emit original actions with response from the server in the res field.
Chain Middleware
If you need emit an action after another will be returned data from the server, you could use the chainlink parameter of the entityOperation. The chainlink is the function that accepts one parameter.
- chainMiddleware only calls the function if original action has status field equal to 'done' (action.status=='done'). * chainMiddleware passes server response (action.res) to that function or original action if it doesn't have res field