Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split 'error' on three different fields; do not unset form-wide submit error if persistentSubmitErrors is true #3890

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/__tests__/helpers/reducer.change.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ const describeChange = (reducer, expect, { fromJS }) => () => {
submitErrors: {
myField: 'submit error'
},
error: 'some global error'
submitFormWideError: 'some global error'
}
}),
change('foo', 'myField', 'different', false, true)
Expand All @@ -293,7 +293,8 @@ const describeChange = (reducer, expect, { fromJS }) => () => {
submitErrors: {
myField: 'submit error'
},
error: 'some global error'
submitFormWideError: 'some global error',
submitErrorsUpToDate: false
}
})
})
Expand Down
11 changes: 7 additions & 4 deletions src/__tests__/helpers/reducer.clearFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const describeClearFields = (reducer, expect, { fromJS }) => () => {
}
},
anyTouched: true,
error: 'some global error'
submitFormWideError: 'some global error'
}
}),
clearFields('foo', false, true, 'myField', 'myOtherField')
Expand All @@ -98,7 +98,8 @@ const describeClearFields = (reducer, expect, { fromJS }) => () => {
myField: 'submit error',
myOtherField: 'submit error'
},
error: 'some global error'
submitErrorsUpToDate: false,
submitFormWideError: 'some global error'
}
})
})
Expand Down Expand Up @@ -266,7 +267,8 @@ const describeClearFields = (reducer, expect, { fromJS }) => () => {
touched: true
}
},
error: 'some global error',
submitErrorsUpToDate: true,
submitFormWideError: 'some global error',
anyTouched: true
}
}),
Expand Down Expand Up @@ -296,7 +298,8 @@ const describeClearFields = (reducer, expect, { fromJS }) => () => {
myField: 'submit error',
myOtherField: 'submit error'
},
error: 'some global error',
submitErrorsUpToDate: false,
submitFormWideError: 'some global error',
anyTouched: true
}
})
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/helpers/reducer.clearSubmitErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const describeClearSubmitErrors = (reducer, expect, { fromJS }) => () => {
submitErrors: {
some: 'error'
},
error: 'form-wide error',
submitFormWideError: 'form-wide error',
active: 'otherField',
triggerSubmit: true
}
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/helpers/reducer.initialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ const describeInitialize = (reducer, expect, { fromJS }) => () => {
initial: {
myField: 'initialValue'
},
error: 'form wide error',
syncFormWideError: 'form wide error',
syncErrors: {
myField: 'field error'
}
Expand All @@ -415,7 +415,7 @@ const describeInitialize = (reducer, expect, { fromJS }) => () => {
initial: {
myField: 'newValue'
},
error: 'form wide error',
syncFormWideError: 'form wide error',
syncErrors: {
myField: 'field error'
}
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/helpers/reducer.stopAsyncValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const describeStopAsyncValidation = (reducer, expect, { fromJS }) => () => {
}
},
asyncValidating: true,
error: 'Previous global error'
asyncFormWideError: 'Previous global error'
}
}),
stopAsyncValidation('foo')
Expand Down Expand Up @@ -219,7 +219,7 @@ const describeStopAsyncValidation = (reducer, expect, { fromJS }) => () => {
touched: true
}
},
error: 'This is a global error'
asyncFormWideError: 'This is a global error'
}
})
})
Expand Down
17 changes: 13 additions & 4 deletions src/__tests__/helpers/reducer.stopSubmit.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
myOtherField: 'Error about myOtherField'
}
},
submitErrorsUpToDate: true,
fields: {
bar: {
myField: {
Expand Down Expand Up @@ -131,6 +132,7 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
submitErrors: {
bar: ['Error about myField', 'Error about myOtherField']
},
submitErrorsUpToDate: true,
fields: {
bar: [
{
Expand Down Expand Up @@ -180,6 +182,7 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
cat: ['Not funny', 'Sleeps too much'],
dog: ['Unhelpful', 'Not house trained']
},
submitErrorsUpToDate: true,
fields: {
cat: {
touched: true
Expand Down Expand Up @@ -274,7 +277,8 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
touched: true
}
},
error: 'some global error',
submitFormWideError: 'some global error',
submitErrorsUpToDate: true,
submitFailed: true
}
})
Expand All @@ -293,7 +297,8 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
}
},
submitting: true,
error: 'Previous global error'
submitFormWideError: 'Previous global error',
submitErrorsUpToDate: true
}
}),
stopSubmit('foo')
Expand Down Expand Up @@ -326,7 +331,8 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
}
},
submitting: true,
error: 'some global error'
submitFormWideError: 'Previous global error',
submitErrorsUpToDate: true
}
}),
stopSubmit('foo', { myField: 'some submit error' })
Expand All @@ -339,6 +345,7 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
submitErrors: {
myField: 'some submit error'
},
submitErrorsUpToDate: true,
fields: {
myField: {
touched: true
Expand Down Expand Up @@ -412,6 +419,7 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
myField: 'Error about myField',
myOtherField: 'Error about myOtherField'
},
submitErrorsUpToDate: true,
fields: {
myField: {
touched: true
Expand Down Expand Up @@ -454,7 +462,8 @@ const describeStopSubmit = (reducer, expect, { fromJS }) => () => {
touched: true
}
},
error: 'This is a global error',
submitFormWideError: 'This is a global error',
submitErrorsUpToDate: true,
submitFailed: true
}
})
Expand Down
3 changes: 1 addition & 2 deletions src/__tests__/helpers/reducer.updateSyncErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ const describeUpdateSyncErrors = (reducer, expect, { fromJS, setIn }) => () => {
myField: 'value',
myOtherField: 'otherValue'
},
syncError: true,
error: 'form wide error'
syncFormWideError: 'form wide error'
}
}),
'foo.syncErrors',
Expand Down
70 changes: 52 additions & 18 deletions src/createReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,11 @@ function createReducer<M, L>(structure: Structure<M, L>) {
result = setIn(result, `values.${field}`, payload)
}
result = deleteInWithCleanUp(result, `asyncErrors.${field}`)
if (!persistentSubmitErrors) {
if (persistentSubmitErrors) {
result = setIn(result, `submitErrorsUpToDate`, false)
} else {
result = deleteInWithCleanUp(result, `submitErrors.${field}`)
result = deleteIn(result, `submitErrorsUpToDate`)
}
result = deleteInWithCleanUp(result, `fields.${field}.autofilled`)
if (touch) {
Expand All @@ -238,7 +241,8 @@ function createReducer<M, L>(structure: Structure<M, L>) {
[CLEAR_SUBMIT_ERRORS](state) {
let result = state
result = deleteInWithCleanUp(result, 'submitErrors')
result = deleteIn(result, 'error')
result = deleteIn(result, 'submitFormWideError')
result = deleteIn(result, `submitErrorsUpToDate`)
return result
},
[CLEAR_ASYNC_ERROR](state, { meta: { field } }) {
Expand All @@ -252,8 +256,11 @@ function createReducer<M, L>(structure: Structure<M, L>) {
fields.forEach(field => {
result = deleteInWithCleanUp(result, `values.${field}`)
result = deleteInWithCleanUp(result, `asyncErrors.${field}`)
if (!persistentSubmitErrors) {
if (persistentSubmitErrors) {
result = setIn(result, `submitErrorsUpToDate`, false)
} else {
result = deleteInWithCleanUp(result, `submitErrors.${field}`)
result = deleteIn(result, `submitErrorsUpToDate`)
}
result = deleteInWithCleanUp(result, `fields.${field}.autofilled`)
if (!keepTouched) {
Expand All @@ -277,7 +284,13 @@ function createReducer<M, L>(structure: Structure<M, L>) {
result = setIn(result, 'active', field)
return result
},
[INITIALIZE](state, { payload, meta: { keepDirty, keepSubmitSucceeded, updateUnregisteredFields } }) {
[INITIALIZE](
state,
{
payload,
meta: { keepDirty, keepSubmitSucceeded, updateUnregisteredFields }
}
) {
const mapData = fromJS(payload)
let result = empty // clean all field state

Expand All @@ -292,10 +305,22 @@ function createReducer<M, L>(structure: Structure<M, L>) {
}

// persist old errors, they will get recalculated if the new form values are different from the old values
const error = getIn(state, 'error')
if (error) {
result = setIn(result, 'error', error)
const syncFormWideError = getIn(state, 'syncFormWideError')
if (syncFormWideError) {
result = setIn(result, 'syncFormWideError', syncFormWideError)
}

// Might not be needed, but test coverage relies on it
const asyncFormWideError = getIn(state, 'asyncFormWideError')
if (asyncFormWideError) {
result = setIn(result, 'asyncFormWideError', asyncFormWideError)
}

const submitFormWideError = getIn(state, 'submitFormWideError')
if (submitFormWideError) {
result = setIn(result, 'submitFormWideError', submitFormWideError)
}

const syncErrors = getIn(state, 'syncErrors')
if (syncErrors) {
result = setIn(result, 'syncErrors', syncErrors)
Expand Down Expand Up @@ -345,7 +370,9 @@ function createReducer<M, L>(structure: Structure<M, L>) {
}

if (!updateUnregisteredFields) {
forEach(keys(registeredFields), name => overwritePristineValue(name))
forEach(keys(registeredFields), name =>
overwritePristineValue(name)
)
}

forEach(keys(newInitialValues), name => {
Expand Down Expand Up @@ -411,13 +438,13 @@ function createReducer<M, L>(structure: Structure<M, L>) {
if (payload && Object.keys(payload).length) {
const { _error, ...fieldErrors } = payload
if (_error) {
result = setIn(result, 'error', _error)
result = setIn(result, 'asyncFormWideError', _error)
}
if (Object.keys(fieldErrors).length) {
result = setIn(result, 'asyncErrors', fromJS(fieldErrors))
}
} else {
result = deleteIn(result, 'error')
result = deleteIn(result, 'asyncFormWideError')
}
return result
},
Expand All @@ -426,23 +453,32 @@ function createReducer<M, L>(structure: Structure<M, L>) {
result = deleteIn(result, 'submitting')
result = deleteIn(result, 'submitFailed')
result = deleteIn(result, 'submitSucceeded')

if (payload && Object.keys(payload).length) {
const { _error, ...fieldErrors } = payload
const isFieldErrorsPresent = !!Object.keys(fieldErrors).length
if (_error) {
result = setIn(result, 'error', _error)
result = setIn(result, 'submitFormWideError', _error)
result = setIn(result, `submitErrorsUpToDate`, true)
} else {
result = deleteIn(result, 'error')
result = deleteIn(result, 'submitFormWideError')
}
if (Object.keys(fieldErrors).length) {
if (isFieldErrorsPresent) {
result = setIn(result, 'submitErrors', fromJS(fieldErrors))
result = setIn(result, `submitErrorsUpToDate`, true)
} else {
result = deleteIn(result, 'submitErrors')
}
if (!_error && !isFieldErrorsPresent) {
result = deleteIn(result, `submitErrorsUpToDate`)
}
result = setIn(result, `submitErrorsUpToDate`, true)
result = setIn(result, 'submitFailed', true)
} else {
result = setIn(result, 'submitSucceeded', true)
result = deleteIn(result, 'error')
result = deleteIn(result, 'submitFormWideError')
result = deleteIn(result, 'submitErrors')
result = deleteIn(result, `submitErrorsUpToDate`)
}
return result
},
Expand Down Expand Up @@ -530,11 +566,9 @@ function createReducer<M, L>(structure: Structure<M, L>) {
[UPDATE_SYNC_ERRORS](state, { payload: { syncErrors, error } }) {
let result = state
if (error) {
result = setIn(result, 'error', error)
result = setIn(result, 'syncError', true)
result = setIn(result, 'syncFormWideError', error)
} else {
result = deleteIn(result, 'error')
result = deleteIn(result, 'syncError')
result = deleteIn(result, 'syncFormWideError')
}
if (Object.keys(syncErrors).length) {
result = setIn(result, 'syncErrors', syncErrors)
Expand Down
Loading