diff --git a/src/index.js b/src/index.js index 90a88331..ae9147ff 100644 --- a/src/index.js +++ b/src/index.js @@ -23,11 +23,11 @@ function normalizeNamespace(fn) { } export function getField(state) { - return path => path.split(/[.[\]]+/).reduce((prev, key) => prev[key], state); + return path => path.split(/[.[\]]+/).filter(x => x).reduce((prev, key) => prev[key], state); } export function updateField(state, { path, value }) { - path.split(/[.[\]]+/).reduce((prev, key, index, array) => { + path.split(/[.[\]]+/).filter(x => x).reduce((prev, key, index, array) => { if (array.length === index + 1) { // eslint-disable-next-line no-param-reassign prev[key] = value; @@ -72,12 +72,13 @@ export const mapMultiRowFields = normalizeNamespace(( // eslint-disable-next-line no-param-reassign entries[key] = { get() { + const tpath = typeof path === `function` ? path.call(null, this) : path; const store = this.$store; - const rows = objectEntries(store.getters[getterType](path)); + const rows = objectEntries(store.getters[getterType](tpath)); return rows .map(fieldsObject => Object.keys(fieldsObject[1]).reduce((prev, fieldKey) => { - const fieldPath = `${path}[${fieldsObject[0]}].${fieldKey}`; + const fieldPath = `${tpath}[${fieldsObject[0]}].${fieldKey}`; return Object.defineProperty(prev, fieldKey, { get() { @@ -95,6 +96,42 @@ export const mapMultiRowFields = normalizeNamespace(( }, {}); }); +export const mapRowFields = normalizeNamespace(( + namespace, + paths, + getterType, + mutationType, +) => { + const pathsObject = Array.isArray(paths) ? arrayToObject(paths) : paths; + return Object.keys(pathsObject).reduce((entries, key) => { + const path = pathsObject[key]; + // eslint-disable-next-line no-param-reassign + entries[key] = { + get() { + const tpath = typeof path === `function` ? path.call(null, this) : path; + const store = this.$store; + const row = store.getters[getterType](tpath); + + if (!row) return {}; + + return Object.keys(row).reduce((prev, fieldKey) => { + const fieldPath = `${tpath}.${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, @@ -110,4 +147,10 @@ export const createHelpers = ({ getterType, mutationType }) => ({ getterType, mutationType, )), + mapRowFields: normalizeNamespace((namespace, paths) => mapRowFields( + namespace, + paths, + getterType, + mutationType, + )), }); diff --git a/src/lib/array-to-object.js b/src/lib/array-to-object.js index 7528582e..452098cb 100644 --- a/src/lib/array-to-object.js +++ b/src/lib/array-to-object.js @@ -1,5 +1,7 @@ export default function arrayToObject(fields = []) { return fields.reduce((prev, path) => { + if (typeof path === `object`) return { ...prev, ...path }; + const key = path.split(`.`).slice(-1)[0]; if (prev[key]) { diff --git a/test/multi-row.test.js b/test/multi-row.test.js index 3cfa43ee..a321156e 100644 --- a/test/multi-row.test.js +++ b/test/multi-row.test.js @@ -20,10 +20,14 @@ describe(`Component initialized with multi row setup.`, () => { +
+ {{user0}}
+
+
+ {{noUser}}
+
+