Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit c8619f4

Browse files
committed
Adding helpful invariant error messages for form existence.
1 parent 03b2913 commit c8619f4

File tree

11 files changed

+52
-8
lines changed

11 files changed

+52
-8
lines changed

src/actions/field-actions.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import getFieldFromState from '../utils/get-field-from-state';
1313
import NULL_ACTION from '../constants/null-action';
1414
import omit from '../utils/omit';
1515
import isNative from '../utils/is-native';
16+
import invariant from 'invariant';
1617

1718
const defaultStrategies = {
1819
get: _get,
@@ -176,6 +177,11 @@ function createFieldActions(s = defaultStrategies) {
176177
if (options.validate) {
177178
const form = s.getForm(getState(), model);
178179

180+
invariant(form,
181+
'Unable to submit form with validation. ' +
182+
'Could not find form for "%s" in the store.',
183+
model);
184+
179185
if (!form.$form.valid) {
180186
return dispatch(NULL_ACTION);
181187
}

src/components/errors-component.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import map from '../utils/map';
55
import iteratee from '../utils/iteratee';
66
import isPlainObject from 'lodash/isPlainObject';
77
import omit from '../utils/omit';
8-
import invariant from 'invariant';
98

109
import getForm from '../utils/get-form';
1110
import getFieldFromState from '../utils/get-field-from-state';
@@ -14,6 +13,7 @@ import isValid from '../form/is-valid';
1413
import resolveModel from '../utils/resolve-model';
1514
import initialFieldState from '../constants/initial-field-state';
1615
import shallowEqual from '../utils/shallow-equal';
16+
import invariant from 'invariant';
1717

1818
const defaultStrategy = {
1919
get: _get,
@@ -184,8 +184,10 @@ function createErrorsClass(s = defaultStrategy) {
184184
const modelString = getModel(model, state);
185185

186186
const form = s.getForm(state, modelString);
187-
invariant(form, `Could not find form state for '${modelString}' model. `
188-
+ 'Please make sure it exists in the store.');
187+
invariant(form,
188+
'Unable to retrieve errors. ' +
189+
'Could not find form for "%s" in the store.',
190+
modelString);
189191

190192
const formValue = form.$form;
191193
const fieldValue = s.getFieldFromState(state, modelString)

src/components/form-component.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import getField from '../utils/get-field';
1616
import { fieldsValid } from '../form/is-valid';
1717
import deepCompareChildren from '../utils/deep-compare-children';
1818
import containsEvent from '../utils/contains-event';
19+
import invariant from 'invariant';
1920

2021
const propTypes = {
2122
component: PropTypes.any,
@@ -373,11 +374,17 @@ function createFormClass(s = defaultStrategy) {
373374

374375
function mapStateToProps(state, { model }) {
375376
const modelString = getModel(model, state);
377+
const form = s.getForm(state, modelString);
378+
379+
invariant(form,
380+
'Unable to create Form component. ' +
381+
'Could not find form for "%s" in the store.',
382+
modelString);
376383

377384
return {
378385
model: modelString,
379386
modelValue: s.get(state, modelString),
380-
formValue: s.getForm(state, modelString),
387+
formValue: form,
381388
};
382389
}
383390

src/reducers/form/change-action-reducer.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import mapValues from '../../utils/map-values';
88
import { createInitialState } from '../form-reducer';
99
import initialFieldState from '../../constants/initial-field-state';
1010
import updateParentForms from '../../utils/update-parent-forms';
11+
import invariant from 'invariant';
1112

1213
function updateFieldValue(field, action, parentModel = undefined) {
1314
const { value, removeKeys, silent, load, model } = action;
@@ -35,6 +36,11 @@ function updateFieldValue(field, action, parentModel = undefined) {
3536
}
3637

3738
if (removeKeys) {
39+
invariant(field && field.$form,
40+
'Unable to remove keys. ' +
41+
'Field for "%s" in store is not an array/object.',
42+
model);
43+
3844
const valueIsArray = Array.isArray(field.$form.value);
3945
const removeKeysArray = Array.isArray(removeKeys)
4046
? removeKeys

src/utils/get-field-form.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import get from './get';
2+
import invariant from 'invariant';
23

34
export default function getFieldForm(state, path) {
45
const formPath = path.slice(0, -1);
56

67
if (!formPath.length) return state;
78

8-
return get(state, formPath);
9+
const form = get(state, formPath);
10+
11+
invariant(form,
12+
'Could not find form for "%s" in the store.',
13+
formPath.join('.'));
14+
15+
return form;
916
}

src/utils/get-field-from-state.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import get from './get';
22
import toPath from './to-path';
33
import getForm from './get-form';
44
import isPlainObject from 'lodash/isPlainObject';
5+
import invariant from 'invariant';
56

67
const defaultStrategy = {
78
getForm,
@@ -16,6 +17,10 @@ export default function getFieldFromState(state, modelString, s = defaultStrateg
1617

1718
if (!modelString.length) return form;
1819

20+
invariant(form,
21+
'Could not find form for "%s" in the store.',
22+
modelString);
23+
1924
const formPath = toPath(form.$form.model);
2025
const fieldPath = toPath(modelString).slice(formPath.length);
2126
const field = get(form, fieldPath);

src/utils/get-form.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ function getForm(state, modelString, s = defaultStrategy) {
8989
return null;
9090
}
9191

92-
return s.get(state, formStateKey);
92+
const form = s.get(state, formStateKey);
93+
94+
return form;
9395
}
9496

9597
export default getForm;

src/utils/update-field.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import i from 'icepick';
22
import get from './get';
33
import mapValues from './map-values';
44
import { createInitialState } from '../reducers/form-reducer';
5+
import invariant from 'invariant';
56

67
function assocIn(state, path, value, fn) {
78
if (!path.length) return i.assign(state, value);
@@ -28,6 +29,10 @@ export function getFieldAndForm(formState, modelPath) {
2829
let field = get(formState, modelPath);
2930
let form = formState;
3031

32+
invariant(form,
33+
'Could not find form for "%s" in the store.',
34+
modelPath);
35+
3136
if (!field) {
3237
const initialValue = get(formState.$form.initialValue, modelPath);
3338

src/utils/update-sub-fields.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default function updateSubFields(state, localPath, newState) {
2727

2828
// only forms can have fields -
2929
// skip if field is not a form
30-
if (!field.$form) return state;
30+
if (!field || !field.$form) return state;
3131

3232
// intermediate value - not mutated outside function
3333
const updatedField = {};

test/field-component-spec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,7 +1855,6 @@ Object.keys(testContexts).forEach((testKey) => {
18551855
const filter = ({ constructor }) =>
18561856
constructor.displayName === 'Connect(Control)';
18571857
const components = TestUtils.findAllInRenderedTree(field, filter);
1858-
console.log(components);
18591858
assert.lengthOf(components, 1, 'exactly one connected Control was rendered');
18601859
const [component] = components;
18611860
const oldStateProps = component.stateProps;

0 commit comments

Comments
 (0)