A
A
Alexander2021-03-13 11:16:03
React
Alexander, 2021-03-13 11:16:03

How to output server errors with Formik?

Hello, help me solve the problem, how can I display server errors, for example, incorrect login, password on the ui side using the Formik library. I used to use Redux-Form and had no problems with it, but after switching to Formik, difficulties began to arise

Example with Redux-Form, erros came from HOC reduxForm to props

import React from 'react'
import { InjectedFormProps, reduxForm } from 'redux-form'
import { required, email } from '../../../utils/validators/validators'
import { createField, Input, Checkbox } from './../../common/FormsControls/FormsControls'
import styles from './../../common/FormsControls/FormsControls.module.css'

type LoginFormOwnProps = {
  captchaUrl: string | null
}

export type LoginFormValuesType = {
  captcha: string
  rememberMe: boolean
  password: string
  email: string
}

type LoginFormValuesTypeKeys = Extract<keyof LoginFormValuesType, string>

const LoginForm: React.FC<InjectedFormProps<LoginFormValuesType, LoginFormOwnProps> & LoginFormOwnProps> = ({
  handleSubmit,
  error,
  captchaUrl,
}) => {
  return (
    <form className={styles.formSubmit} onSubmit={handleSubmit}>
      {createField<LoginFormValuesTypeKeys>(Input, 'email', 'Email', 'email', [required, email])}
      {createField<LoginFormValuesTypeKeys>(Input, 'password', 'Password', 'password', [required])}
      <div className={styles.rememberMe}>
        {createField(Checkbox, 'checkbox', undefined, 'rememberMe', null, { id: 'rememberMe' })}
        <label htmlFor='rememberMe'>remember me</label>
      </div>
      {captchaUrl && (
        <div className={styles.captcha}>
          <img src={captchaUrl} alt='' />
          {createField(Input, 'text', 'Symbols from image', 'captcha', [required], {
            autoFocus: true,
          })}
        </div>
      )}
      {error && <div className={styles.formSummaryError}>{error}</div>}
      <div>
        <button className={styles.btn}>Login</button>
      </div>
    </form>
  )
}

export default reduxForm<LoginFormValuesType, LoginFormOwnProps>({ form: 'login' })(LoginForm)


And here is what Formik looks like

import React from 'react'
import styles from './../../common/FormsControls/FormsControls.module.css'
import { FormikProps, withFormik } from 'formik'
import * as Yup from 'yup'
import FormsControl from '../../common/FormsControls/FormsControls'

interface OtherProps {
  captchaUrl: string | null
}
export interface LoginFormValues {
  captcha: string
  rememberMe: boolean
  password: string
  email: string
}

const Form = (props: OtherProps & FormikProps<LoginFormValues>) => {
  const { values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, captchaUrl } = props

  return (
    <form className={styles.formSubmit} onSubmit={handleSubmit}>
      <FormsControl control='input' type='email' name='email' />
      <FormsControl control='input' type='password' name='password' />

      <div className={styles.rememberMe}>
        {/* <FormsControl control='checkbox' label='Remember Me' name='rememberMe' /> */}
      </div>

      {captchaUrl && (
        <div className={styles.captcha}>
          <img src={captchaUrl} alt='captcha' />
          <FormsControl control='input' type='text' name='captcha' />

          {/* {createField(Input, 'text', 'Symbols from image', 'captcha', [required], {
            autoFocus: true,
          })} */}
        </div>
      )}

      {/* {errors && <div className={styles.formSummaryError}>{errors}</div>} */}
      {Object.values(errors).map((msg) => (
        <>
          {msg}
          <br />
        </>
      ))}

      <div>
        <button className={styles.btn} type='submit'>
          Login
        </button>
      </div>
    </form>
  )
}

interface MyFormProps {
  onLogin: (values: any) => void
  captchaUrl: string | null
}

const LoginForm = withFormik<MyFormProps, LoginFormValues>({
  mapPropsToValues: () => ({
    email: '',
    password: '',
    rememberMe: true,
    captcha: '',
  }),
  validationSchema: Yup.object().shape({
    email: Yup.string().email('Invalid email format').required('Required'),
    password: Yup.string().required('Required'),
    // rememberMe: Yup.boolean().required('Required'),
    // captcha: Yup.string().required('Required'),
  }),
  handleSubmit(values: LoginFormValues, { props, setSubmitting, setStatus }) {
    setSubmitting(false)
    props.onLogin(values)
    setStatus() //вывод ошибок
  },
})(Form)

export default LoginForm


I just know that errors are displayed through setStatus, but I don’t need to handle errors through different conditions, I just need to display their text, which is already prepared on the backend and sits in the object

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question