Repository: erikras/redux-form
Pull request #645 (2016-02-13 11:49:29)

Handle array normalization properly
Here's code to handle the array syntax without nested properties (i.e. `'cats[]': (array) => ...`). This should pass the test introduced in dc581172784686af13754c0d07cb9f502eb9fde2. I also added a couple of other tests to ensure nested arrays work similarly.


Patch:
diff --git a/src/normalizeFields.js b/src/normalizeFields.js
index 4972a9aa..56e331e9 100644
--- a/src/normalizeFields.js
+++ b/src/normalizeFields.js
@@ -31,24 +31,35 @@ function extractKey(field) {
 }
 
 function normalizeField(field, fullFieldPath, state, previousState, values, previousValues, normalizers) {
-  if (field.isArray && field.nestedPath) {
-    const array = state && state[field.key] || [];
-    const previousArray = previousState && previousState[field.key] || [];
-    const nestedField = extractKey(field.nestedPath);
+  if (field.isArray) {
+    if (field.nestedPath) {
+      const array = state && state[field.key] || [];
+      const previousArray = previousState && previousState[field.key] || [];
+      const nestedField = extractKey(field.nestedPath);
+
+      return array.map((nestedState, i) => {
+        nestedState[nestedField.key] = normalizeField(
+          nestedField,
+          fullFieldPath,
+          nestedState,
+          previousArray[i],
+          values,
+          previousValues,
+          normalizers
+        );
+
+        return nestedState;
+      });
+    }
+
+    const normalizer = normalizers[fullFieldPath];
 
-    return array.map((nestedState, i) => {
-      nestedState[nestedField.key] = normalizeField(
-        nestedField,
-        fullFieldPath,
-        nestedState,
-        previousArray[i],
-        values,
-        previousValues,
-        normalizers
-      );
-
-      return nestedState;
-    });
+    return normalizer(
+      state && state[field.key],
+      previousState && previousState[field.key],
+      values,
+      previousValues
+    );
   } else if (field.nestedPath) {
     const nestedState = state && state[field.key] || {};
     const nestedField = extractKey(field.nestedPath);


Test patch:
diff --git a/src/__tests__/reducer.spec.js b/src/__tests__/reducer.spec.js
index cff064d3..e47949f5 100644
--- a/src/__tests__/reducer.spec.js
+++ b/src/__tests__/reducer.spec.js
@@ -3205,6 +3205,8 @@ describe('reducer', () => {
           'person.name': (name) => name && name.toUpperCase(),
           'pets[].name': (name) => name && name.toLowerCase(),
           'cats[]': (array) => array && array.map(value => value.toUpperCase()),
+          'programming[].langs[]': (array) => array && array.slice(0).sort(),
+          'some.numbers[]': (array) => array && array.filter(n => n % 2 === 0),
           'a.very.deep.object.property': (value) => value && value.toUpperCase(),
           'my[].deeply[].nested.arrayItem': (value) => value && value.toUpperCase()
         }
@@ -3226,6 +3228,14 @@ describe('reducer', () => {
             'garfield',
             'whiskers'
           ],
+          programming: [{
+            langs: ['ml', 'ocaml', 'lisp', 'haskell', 'f#']
+          }, {
+            langs: ['smalltalk', 'ruby', 'java', 'c#', 'c++']
+          }],
+          some: {
+            numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+          },
           a: {
             very: {
               deep: {
@@ -3294,6 +3304,14 @@ describe('reducer', () => {
             'GARFIELD',
             'WHISKERS'
           ],
+          programming: [{
+            langs: ['f#', 'haskell', 'lisp', 'ml', 'ocaml']
+          }, {
+            langs: ['c#', 'c++', 'java', 'ruby', 'smalltalk']
+          }],
+          some: {
+            numbers: [2, 4, 6, 8, 10]
+          },
           a: {
             very: {
               deep: {