I'm building a flux app that involves many different types of data, and the CRUD style modification of the resources. This leads to the a large number of ActionTypes. Most of them follow the same pattern, REQUEST_ENTITY, REQUEST_ENTITY_SUCCESS, REQUEST_ENTITY_ERROR
, and so on.
How do I separate them into namespaced constants?
Ideally instead of accessing them like:
ActionTypes.REQUEST_ENTITY
I could access them in a more sane way like,
ActionTypes.entity.REQUEST
You could simply merge multiple objects (perhaps exported from different files) into ActionTypes
.
// entity_actions.js
module.exports = {
entity: {
REQUEST: "entity.REQUEST",
DELETE: "entity.DELETE",
}
};
// user_actions.js
module.exports = {
user: {
REQUEST: "user.REQUEST",
DELETE: "user.DELETE",
}
};
// actions.js
var entityActions = require("./entity_actions");
var userActions = require("./user_actions");
var ActionTypes = Object.assign({}, entityActions, userActions);
You can use something like Underscore#extend
or object-assign if Object.assign
isn't available in your environment.
I personally use a small module I called nestedKeyMirror
that takes a big nested object and automatically generates values based on the nesting:
function nestedKeyMirror(obj, namespace) {
namespace = namespace || [];
for (key in obj) {
if (obj.hasOwnProperty(key) && obj[key] === null) {
obj[key] = namespace.concat([key]).join(":");
} else if (obj.hasOwnProperty(key) && typeof obj[key] === "object") {
obj[key] = nestedKeyMirror(obj[key], namespace.concat([key]));
}
}
return obj;
}
For example, in one app, I have the following action types defined:
var actionTypes = nestedKeyMirror({
LAYOUT: {
RESIZE_PANE: null
},
CANVAS: {
SET_PROPERTY: null
},
SHAPES: {
ADD: null,
SET_PROPERTY: null,
SEND_BACKWARD: null,
SEND_FORWARD: null,
SEND_TO_BACK: null,
SEND_TO_FRONT: null
},
SELECTION: {
SELECT: null,
DESELECT_ALL: null
},
HISTORY: {
ADD: null,
SELECT_INDEX: null
}
});
This would give, e.g., actionTypes.SHAPES.ADD
with an automatically-generated string value of "SHAPES:ADD"
. This technique can be combined with the object-merging strategy, above, to easily create deeply nested action type constants.
[Update: it looks like someone recently released a package that does the nested key mirroring on npm: keymirror-nested]
If the problem is that all your action types look similar, you could easily create a function to generate them (ES6 computed property syntax used here):
function generateActionType(type, base) {
return {
[base]: `${base}_${type}`,
[`${base}_SUCCESS`]: `${base}_${type}_SUCCESS`,
[`${base}_ERROR`]: `${base}_${type}_ERROR`
};
}
ActionTypes.entity = {};
Object.assign(ActionTypes.entity, generateActionType("ENTITY", "REQUEST"));
Object.assign(ActionTypes.entity, generateActionType("ENTITY", "DELETE"));
ActionTypes.entity.REQUEST_SUCCESS === "REQUEST_ENTITY_SUCCESS";