RocketPartial
What is a RocketPartial?
The entry point for RocketJump is called rj
.
The rj
function takes any number of parameters, each of which is a configuration object or another RocketJump Partial
, and returns a RocketJump Partial
. This allows for recursive composition (see composition). To stop composing and get a real rocketjump, you have to invoke the last RocketJump Partial
.
import { rj } from 'redux-rocketjump';
rj({ /* put yout configuration here */ })
Configuration options
actions (object|function)
This configuration option was called
proxyActions
in version 1.*
This property can be used to customize the generated actions by adding more ones.
This property can be used in two ways
- if it contains an object, then a new action dispatcher is generated for each of the keys. Each value must be a function that takes one argument, that is an object containing the default
load
andunload
action dispatchers, and returns an action dispatcher. - it it contains a function, that function is invoked with an object containing the default
load
andunload
action dispatchers as argument, and must return an object containing, for each key, an action dispatching function
Examples: implement complex behaviours
{
// ... other config options ...
actions: {
loadMore: ({ load }) => (params = {}, meta = {}) => load(params, { ...meta, more: true })
}
}
{
// ... other config options ...
actions: ({ load }) => {
return {
loadMore: (params = {}, meta = {}) => load(params, { ...meta, more: true })
}
}
}
selectors (object|function)
This configuration options was called
proxySelectors
in version 1.*
This property can be used to customize the generated selectors by adding more ones.
This property can be used in two ways
- if it contains an object, then a new selector is generated for each of the keys. Each value must be a function that takes one argument, that is an object containing the default
isLoading
,getData
andgetError
selectors, and returns a selector. - it it contains a function, that function is invoked with an object containing the default
isLoading
,getData
andgetError
selectors as argument, and must return an object containing, for each key, a selector
Examples: add a custom property
{
// ... other config options ...
selectors: {
getData: ({ getData }) => createSelector(getData, todos =>
todos === null ? null : todos.map(todo => ({
...todo,
asReadMe: `* [${todo.done ? 'v' : ''}] ${todo.title}`
}))
)
}
}
{
// ... other config options ...
selectors: ({ getData }) => ({
getData: createSelector(getData, todos =>
todos === null ? null : todos.map(todo => ({
...todo,
asReadMe: `* [${todo.done ? 'v' : ''}] ${todo.title}`
}))
)
})
}
reducer (function)
This configuration option was called
proxyReducer
in version 1.*
This property can be used to customize the generated reducer.
If given, this property is expected to contain a function that is called with the automatically generated reducer and that must return the reducer to be used in place of the default one
Example: translate error messages
{
// ... other config options ...
proxyReducer: oldReducer => (state, action) => {
switch(action.type) {
case 'MY_COOL_ACTION_ERROR':
return {
...state,
errors: translateAll(action.errors)
}
default:
return oldReducer(state, action);
}
}
}
dataReducer (function)
If this property is set, it must contain a sub reducer to handle the ${type}_SUCCESS
action on the piece of state related to data. The default implementation is:
(prevState, { type, payload }) => payload.data
Example: deserialize date objects
{
// ... other config options ...
dataReducer: (oldData, { type, payload }) => {
return payload.map(item => ({
...item,
date: new Date(item.date)
}))
}
}
effectCaller (effect)
This configuration option was called
callEffect
in version 1.*
If this property is given then its value is used instead of the call
function from redux-saga to call the api function. As such, this property must contain a generator.
Example: manage authentication tokens
{
// ... other config options ...
effectCaller: function *(apiFn, ...args) {
const token = yield select(state => state.auth.accessToken)
const result = yield call(apiFn, ...args, token)
return result
}
}
effectExtraParams (generator|generator[])
This configuration option was called
apiExtraParams
in version 1.*
If this property is given, it is expected to be a generator or an array of generators. These are used sequentially to compute additional parameters to be passed to the api
function in the params
argument.
The first generator is invoked with the params
and meta
objects as its arguments, and its output is merged into the params
object itself. Each of following generators is invoked with the params
object obtained after the last run and the meta
object, and the output is merged again in the same way of the first run. In order to achieve this, each generator must return an object. The params
object obtained after the last generator has been invoked and its result has been blended is used to run the asynchronous task.
Example: manage pagination data
{
// ... other config options ...
effectExtraParams: function *(params, meta) {
if (meta.loadMore) {
const next = yield select(state.pagination.next)
return { next }
}
}
}
needEffect (generator)
If this property is provided, it is expected to be a generator, which is invoked right before the api
task begins to run: if the generator yields a falsy value, the api
run is skipped.
Example: skip some calls to an API because we are caching the value
rj({
// ... other config options ...
proxyActions: {
load: ({ load }) =>
(params = {}, meta = {}) =>
load(params, { ...meta, cache: true }),
},
needEffect: function *(meta) {
if (!meta.cache) {
return true
}
const { getData } = makeSelectors(config.state)
const data = yield select(getData)
return data === null
}
})
successEffect (generator|generator[])
If this property is provided, it is expected to be a generator or an array of generators. These generators are invoked when the Promise returned by the api
function resolves, and each of them is called with the data obtained from the promise resolution along with the meta
object passed in the action dispatcher.
Example: do something with the result
{
// ... other config options ...
successEffect: function *(data, meta) {
if (meta.successMessage) {
yield put(showSuccessMessage(meta.successMessage))
}
}
}
failureEffect (generator|generator[])
If this property is provided, it is expected to be a generator or an array of generators. These generators are invoked when the Promise returned by the api
function rejects, and each of them is called with the data obtained from the promise rejection along with the meta
object passed in the action dispatcher.
Example: alert errors
{
// ... other config options ...
failureEffect: function *(error) {
yield put(showErrorToast(`Sorry our monkeys are trying to do their best, ${error.message}`))
}
}
takeEffect (effect)
The effect that describes how the tasks spawned by the main action type are handled. The default value is takeLatestAndCancel
: it spawns a task every time the load
function is called, and cancels any previous pending tasks. This is usually the wanted behaviour in case of GET requests. If you need a different behavior can choose one from redux-rocketjump/effects
, or you can implement a custom one.
takeEffectArgs (any[])
If provided, it must be an array of additional params to be passed to takeEffect
. The elements contained in the array are arbitrary. When takeEffect
is used, these params are spread as arguments.
mapLoadingAction (function)
If provided, it must be a function that is applied to the action dispatched by a load
call and that should be used to transform the action before it is dispatched. It must return the modified action.
mapSuccessAction (function)
If provided, it must be a function that is applied to the action dispatched when api
completes before it is dispatched. It must return the modified action.
mapFailureAction (function)
If provided, it must be a function that is applied to the action dispatched when api
fails before it is dispatched. It must return the modified action.
composeReducer (function[])
It is possibile to pass a list of reducer functions to be composed together, along with the default reducer. Composition here means that any action dispatched to the reducer built by rocketjump will be dispatched through the default reducer, and then through all this list of reducers. This allows the combination of reducers handling different action types
Example: combining more HOR plugins
{
// ... other config options ...
composeReducer: [
makeUpdateReducer(
SET_USER_STARRED,
'data.list',
undefined,
({ payload: { data: { starred } } }, obj) => ({ ...obj, starred }),
),
makeRemoveListReducer(DELETE_USER),
makeUpdateReducer(UPDATE_USER, 'data.list'),
]
}