Repository: erikras/redux-form
Pull request #632 (2016-02-10 06:01:59)

Fix for #630
I forgot to deal with the other descending readField() case. This adds a test and fix for that case. Thanks @stevengoldberg for the test case.



Patch:
diff --git a/src/readField.js b/src/readField.js
index 47fe1293..2aba7ee6 100644
--- a/src/readField.js
+++ b/src/readField.js
@@ -24,6 +24,7 @@ const readField = (state, fieldName, pathToHere = '', fields, syncErrors, asyncV
   if (openIndex > 0 && closeIndex !== openIndex + 1) {
     throw new Error('found [ not followed by ]');
   }
+
   if (openIndex > 0 && (dotIndex < 0 || openIndex < dotIndex)) {
     // array field
     const key = fieldName.substring(0, openIndex);
@@ -58,6 +59,7 @@ const readField = (state, fieldName, pathToHere = '', fields, syncErrors, asyncV
       const dest = rest ? fieldArray[index] : {};
       const nextPath = `${pathToHere}${key}[${index}]${rest ? '.' : ''}`;
       const nextPrefix = `${prefix}${key}[]${rest ? '.' : ''}`;
+
       const result = readField(fieldState, rest, nextPath, dest, syncErrors,
         asyncValidate, isReactNative, props, callback, nextPrefix);
       if (!rest) { // if nothing after [] in field name, assign directly to array
@@ -77,8 +79,9 @@ const readField = (state, fieldName, pathToHere = '', fields, syncErrors, asyncV
     if (!fields[key]) {
       fields[key] = {};
     }
-    return readField(state[key] || {}, rest, pathToHere + key + '.', fields[key], syncErrors, asyncValidate,
-      isReactNative, props, callback);
+    const nextPath = pathToHere + key + '.';
+    return readField(state[key] || {}, rest, nextPath, fields[key], syncErrors, asyncValidate,
+      isReactNative, props, callback, nextPath);
   }
   const name = pathToHere + fieldName;
   const field = fields[fieldName] || {};


Test patch:
diff --git a/src/__tests__/createReduxForm.spec.js b/src/__tests__/createReduxForm.spec.js
index 6e7cf613..96cd9cfd 100644
--- a/src/__tests__/createReduxForm.spec.js
+++ b/src/__tests__/createReduxForm.spec.js
@@ -1234,6 +1234,63 @@ describe('createReduxForm', () => {
       });
   });
 
+  // Test to demonstrate bug: https://github.com/erikras/redux-form/issues/630
+  it('should add array values when root is not an array', () => {
+    const store = makeStore();
+    const form = 'testForm';
+    const Decorated = reduxForm({
+      form,
+      fields: [
+        'acknowledgements.items[].number',
+        'acknowledgements.items[].name',
+        'acknowledgements.show'
+      ]
+    })(Form);
+    const dom = TestUtils.renderIntoDocument(
+      <Provider store={store}>
+        <Decorated/>
+      </Provider>
+    );
+    const stub = TestUtils.findRenderedComponentWithType(dom, Form);
+
+    expect(stub.props.fields.acknowledgements).toBeA('object');
+    expect(stub.props.fields.acknowledgements.items).toBeA('array');
+    expect(stub.props.fields.acknowledgements.items.length).toBe(0);
+    expect(stub.props.fields.acknowledgements.items.addField).toBeA('function');
+
+    // add field
+    stub.props.fields.acknowledgements.items.addField({
+      number: 1,
+      name: 'foo'
+    });
+
+    // check field
+    expect(stub.props.fields.acknowledgements.items.length).toBe(1);
+    expect(stub.props.fields.acknowledgements.items[0]).toBeA('object');
+    expectField({
+      field: stub.props.fields.acknowledgements.items[0].number,
+      name: 'acknowledgements.items[0].number',
+      value: 1,
+      initial: 1,
+      valid: true,
+      dirty: false,
+      error: undefined,
+      touched: false,
+      visited: false
+    });
+    expectField({
+      field: stub.props.fields.acknowledgements.items[0].name,
+      name: 'acknowledgements.items[0].name',
+      value: 'foo',
+      initial: 'foo',
+      valid: true,
+      dirty: false,
+      error: undefined,
+      touched: false,
+      visited: false
+    });
+  });
+
   // Test to demonstrate bug: https://github.com/erikras/redux-form/issues/468
   it('should add array values with DEEP defaults', () => {
     const store = makeStore();