diff --git a/awx/ui_next/src/components/FormField/FormSubmitError.jsx b/awx/ui_next/src/components/FormField/FormSubmitError.jsx index 714ca4119d87..44ad062f592e 100644 --- a/awx/ui_next/src/components/FormField/FormSubmitError.jsx +++ b/awx/ui_next/src/components/FormField/FormSubmitError.jsx @@ -2,6 +2,26 @@ import React, { useState, useEffect } from 'react'; import { useFormikContext } from 'formik'; import { Alert } from '@patternfly/react-core'; +const findErrorStrings = (obj, messages = []) => { + if (typeof obj === 'string') { + messages.push(obj); + } else if (typeof obj === 'object') { + Object.keys(obj).forEach(key => { + const value = obj[key]; + if (typeof value === 'string') { + messages.push(value); + } else if (Array.isArray(value)) { + value.forEach(arrValue => { + messages = findErrorStrings(arrValue, messages); + }); + } else if (typeof value === 'object') { + messages = findErrorStrings(value, messages); + } + }); + } + return messages; +}; + function FormSubmitError({ error }) { const [errorMessage, setErrorMessage] = useState(null); const { setErrors } = useFormikContext(); @@ -18,14 +38,7 @@ function FormSubmitError({ error }) { const errorMessages = error.response.data; setErrors(errorMessages); - let messages = []; - Object.values(error.response.data).forEach(value => { - if (Array.isArray(value)) { - messages = messages.concat(value); - } else { - messages.push(value); - } - }); + const messages = findErrorStrings(error.response.data); setErrorMessage(messages.length > 0 ? messages : null); } else { /* eslint-disable-next-line no-console */ diff --git a/awx/ui_next/src/components/FormField/FormSubmitError.test.jsx b/awx/ui_next/src/components/FormField/FormSubmitError.test.jsx index 7dd41922bdb9..30656b4d627a 100644 --- a/awx/ui_next/src/components/FormField/FormSubmitError.test.jsx +++ b/awx/ui_next/src/components/FormField/FormSubmitError.test.jsx @@ -52,4 +52,30 @@ describe('', () => { expect(global.console.error).toHaveBeenCalledWith(error); global.console = realConsole; }); + + test('should display error message if field error is nested', async () => { + const error = { + response: { + data: { + name: 'There was an error with name', + inputs: { + url: 'Error with url', + }, + }, + }, + }; + let wrapper; + await act(async () => { + wrapper = mountWithContexts( + {() => } + ); + }); + wrapper.update(); + expect( + wrapper.find('Alert').contains(
There was an error with name
) + ).toEqual(true); + expect(wrapper.find('Alert').contains(
Error with url
)).toEqual( + true + ); + }); });