Skip to content

Commit

Permalink
Add mapObjectFields() to add object properties using template e.g. 'p…
Browse files Browse the repository at this point in the history
…roperty.*'
  • Loading branch information
anikolaev committed Oct 16, 2018
1 parent 65842ca commit fd0c1ad
Showing 1 changed file with 49 additions and 1 deletion.
50 changes: 49 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ function normalizeNamespace(fn) {
}

export function getField(state) {
return path => path.split(/[.[\]]+/).reduce((prev, key) => prev[key], state);
return path => {
if (path == '') {
return state;
} else {
return path.split(/[.[\]]+/).reduce((prev, key) => prev[key], state);
}
}
}

export function updateField(state, { path, value }) {
Expand Down Expand Up @@ -90,11 +96,53 @@ export const mapMultiRowFields = normalizeNamespace((
}, {});
});

export const mapObjectFields = normalizeNamespace((
namespace,
paths,
getterType,
mutationType,
) => {
const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths;

return Object.keys(pathsObject).reduce((entries, key) => {
let path = pathsObject[key].replace(/\.?\*/g, '');

// eslint-disable-next-line no-param-reassign
entries[key] = {
get() {
const store = this.$store;

const fieldsObject = store.getters[getterType](path);
if (!fieldsObject) {
return {}
}

return Object.keys(fieldsObject).reduce((prev, fieldKey) => {
const fieldPath = path ? `${path}.${fieldKey}`: fieldKey;

return Object.defineProperty(prev, fieldKey, {
get() {
return store.getters[getterType](fieldPath);
},
set(value) {
store.commit(mutationType, { path: fieldPath, value });
},
});
}, {});
},
};

return entries;
}, {});
});

export const createHelpers = ({ getterType, mutationType }) => ({
[getterType]: getField,
[mutationType]: updateField,
mapFields: normalizeNamespace((namespace, fields) =>
mapFields(namespace, fields, getterType, mutationType)),
mapMultiRowFields: normalizeNamespace((namespace, paths) =>
mapMultiRowFields(namespace, paths, getterType, mutationType)),
mapObjectFields: normalizeNamespace((namespace, paths) =>
mapObjectFields(namespace, paths, getterType, mutationType)),
});

2 comments on commit fd0c1ad

@stijnjanmaat
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anikolaev is it possible to make the property enumerable?

return Object.defineProperty(prev, fieldKey, {
  enumerable: true
...

Then it would be easier to walk all properties of the object.

@anikolaev
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stijnjanmaat Yes, I think it is a good idea and it is implemented in PR: https://github.com/maoberlehner/vuex-map-fields/pull/45/files#diff-1fdf421c05c1140f6d71444ea2b27638R124
This code is older.
I think it should be implemented for arrays too: maoberlehner#28 (comment)

Please sign in to comment.