Home > Software design >  Registration Form with Formik,Yup,Mui not working
Registration Form with Formik,Yup,Mui not working

Time:12-29

Good afternoon everyone. I'm trying to create a registration form using Formik, MUI, and yup. I did the same thing with my login and it's working perfectly with the backend post etc. Also, my auth/register for backend is working, tested with the postman. My problem is whenever I press the Register Button nothing happens. Not even the console logging of my 'Test' String.

import {
    Box,
    Button,
    MenuItem,
    TextField,
    Typography,
    useMediaQuery,
    useTheme,
} from '@mui/material'
import { Formik } from 'formik'
import { useNavigate } from 'react-router-dom'
import * as yup from 'yup'

const registerSchema = yup.object().shape({
    firstName: yup.string().required('required'),
    lastName: yup.string().required('required'),
    userType: yup.string().required('required'),
    userName: yup.string().required('required'),
    email: yup.string().email('invalid email').required('required'),
    password: yup.string().required('required'),
    confirmPassword: yup.string().required('required'),
})

const initialValuesRegister = {
    firstName: '',
    lastName: '',
    userType: '',
    userName: '',
    email: '',
    password: '',
    confirmPassword: '',
}

const type = [
    {
        value: 'Student',
        label: 'Student',
    },
    {
        value: 'Teacher',
        label: 'Teacher',
    },
]

const FormRegister = () => {
    const { palette } = useTheme()
    const navigate = useNavigate()
    const isNonMobile = useMediaQuery('(min-width:600px)')

    const register = async (values, onSubmitProps) => {
        const savedUserResponse = await fetch(
            'http://localhost:3001/auth/register',
            {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(values),
            }
        )

        const savedUser = await savedUserResponse.json()
        onSubmitProps.resetForm()

        if (savedUser) {
            console.log(savedUser)
            navigate('/')
        }
    }

    const handleFormSubmit = async (values, onSubmitProps) => {
        console.log('Test')
        console.log(values, onSubmitProps)
        await register(values, onSubmitProps)
    }

    return (
        <Formik
            onSubmit={handleFormSubmit}
            initialValues={initialValuesRegister}
            validationSchema={registerSchema}
        >
            {({
                values,
                errors,
                touched,
                handleBlur,
                handleChange,
                handleSubmit,
                resetForm,
            }) => (
                <form onSubmit={handleSubmit}>
                    <Box
                        display="grid"
                        gap="30px"
                        gridTemplateColumns="repeat(4, minmax(0, 1fr))"
                        sx={{
                            '& > div': { gridColumn: isNonMobile ? undefined : 'span 4' },
                        }}
                    >
                        <TextField
                            label="First Name"
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.firstName}
                            name="firstName"
                            error={Boolean(touched.firstName) && Boolean(errors.firstName)}
                            helperText={touched.firstName && errors.firstName}
                            sx={{ gridColumn: 'span 2' }}
                        />
                        <TextField
                            label="Last Name"
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.lastName}
                            name="lastName"
                            error={Boolean(touched.lastName) && Boolean(errors.lastName)}
                            helperText={touched.lastName && errors.lastName}
                            sx={{ gridColumn: 'span 2' }}
                        />
                        <TextField
                            id="outlined-select"
                            select
                            label="Select Type"
                            defaultValue="Student"
                        >
                            {type.map((option) => (
                                <MenuItem key={option.value} value={option.value}>
                                    {option.label}
                                </MenuItem>
                            ))}
                        </TextField>
                        <TextField
                            label="User Name"
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.userName}
                            name="userName"
                            error={Boolean(touched.userName) && Boolean(errors.userName)}
                            helperText={touched.userName && errors.userName}
                            sx={{ gridColumn: 'span 4' }}
                        />
                        <TextField
                            label="Email"
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.email}
                            name="email"
                            error={Boolean(touched.email) && Boolean(errors.email)}
                            helperText={touched.email && errors.email}
                            sx={{ gridColumn: 'span 4' }}
                        />
                        <TextField
                            label="Password"
                            type="password"
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.password}
                            name="password"
                            error={Boolean(touched.password) && Boolean(errors.password)}
                            helperText={touched.password && errors.password}
                            sx={{ gridColumn: 'span 4' }}
                        />
                        <TextField
                            label="Confirm Password"
                            type="password"
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.confirmPassword}
                            name="confirmPassword"
                            error={
                                Boolean(touched.confirmPassword) &&
                                Boolean(errors.confirmPassword)
                            }
                            helperText={touched.confirmPassword && errors.confirmPassword}
                            sx={{ gridColumn: 'span 4' }}
                        />
                    </Box>
                    {/* BUTTONS */}
                    <Box>
                        <Button
                            fullWidth
                            type="submit"
                            sx={{
                                m: '2rem 0',
                                p: '1rem',
                                backgroundColor: palette.primary.main,
                                color: palette.background.alt,
                                '&:hover': { color: palette.primary.main },
                            }}
                        >
                            REGISTER
                        </Button>
                        <Typography
                            onClick={() => {
                                navigate('/')
                                resetForm()
                            }}
                            sx={{
                                textDecoration: 'underline',
                                color: palette.primary.main,
                                '&:hover': {
                                    cursor: 'pointer',
                                    color: palette.primary.light,
                                },
                            }}
                        >
                            Already have an account? Login here
                        </Typography>
                    </Box>
                </form>
            )}
        </Formik>
    )
}

export default FormRegister

CodePudding user response:

You need to provide values as parameter in onSubmit to pass to your handleFormSubmit method and also change form with Form because you using Formik so why not use all of it. In initialValues userType is not getting updated and that's why your onSubmit is not getting called ,so you have to replace your existing code to this so it can update userType value because it's required in the validationSchema

   <TextField
      id="outlined-select"
      select
      label="Select Type"
      name="userType"
      value={values.userType}
      onChange={handleChange}
      defaultValue="student"
    >

Full code:

import {
  Box,
  Button,
  MenuItem,
  TextField,
  Typography,
  useMediaQuery,
  useTheme
} from "@mui/material";
import { Formik, Form } from "formik";
import { useNavigate } from "react-router-dom";
import * as yup from "yup";

const registerSchema = yup.object().shape({
  firstName: yup.string().required("required"),
  lastName: yup.string().required("required"),
  userType: yup.string().required("required"),
  userName: yup.string().required("required"),
  email: yup.string().email("invalid email").required("required"),
  password: yup.string().required("required"),
  confirmPassword: yup.string().required("required")
});

const initialValuesRegister = {
  firstName: "",
  lastName: "",
  userType: "",
  userName: "",
  email: "",
  password: "",
  confirmPassword: ""
};

const type = [
  {
    value: "Student",
    label: "Student"
  },
  {
    value: "Teacher",
    label: "Teacher"
  }
];

const FormRegister = () => {
  const { palette } = useTheme();
  // const navigate = useNavigate();
  const isNonMobile = useMediaQuery("(min-width:600px)");

  const register = async (values) => {
    const savedUserResponse = await fetch(
      "http://localhost:3001/auth/register",
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(values)
      }
    );

    const savedUser = await savedUserResponse.json();
  

    if (savedUser) {
      console.log(savedUser);
      navigate("/");
    }
  };

  const handleFormSubmit = async (values) => {
    console.log("Test");
    console.log(values);
    // await register(values);
  };

  return (
    <Formik
      initialValues={initialValuesRegister}
      onSubmit={(values, {resetForm}) => {
           handleFormSubmit(values);
           resetForm()
      }}
      validationSchema={registerSchema}
    >
      {({
        values,
        errors,
        touched,
        handleBlur,
        handleChange,
        handleSubmit,
        resetForm
      }) => (
        <Form>
          <Box
            display="grid"
            gap="30px"
            gridTemplateColumns="repeat(4, minmax(0, 1fr))"
            sx={{
              "& > div": { gridColumn: isNonMobile ? undefined : "span 4" }
            }}
          >
            <TextField
              label="First Name"
              onBlur={handleBlur}
              onChange={handleChange}
              value={values.firstName}
              name="firstName"
              error={Boolean(touched.firstName) && Boolean(errors.firstName)}
              helperText={touched.firstName && errors.firstName}
              sx={{ gridColumn: "span 2" }}
            />
            <TextField
              label="Last Name"
              onBlur={handleBlur}
              onChange={handleChange}
              value={values.lastName}
              name="lastName"
              error={Boolean(touched.lastName) && Boolean(errors.lastName)}
              helperText={touched.lastName && errors.lastName}
              sx={{ gridColumn: "span 2" }}
            />
            <TextField
              id="outlined-select"
              select
              label="Select Type"
              name="userType"
              value={values.userType}
              onChange={handleChange}
              defaultValue="student"
            >
              {type.map((option) => (
                <MenuItem key={option.value} value={option.value}>
                  {option.label}
                </MenuItem>
              ))}
            </TextField>
            <TextField
              label="User Name"
              onBlur={handleBlur}
              onChange={handleChange}
              value={values.userName}
              name="userName"
              error={Boolean(touched.userName) && Boolean(errors.userName)}
              helperText={touched.userName && errors.userName}
              sx={{ gridColumn: "span 4" }}
            />
            <TextField
              label="Email"
              onBlur={handleBlur}
              onChange={handleChange}
              value={values.email}
              name="email"
              error={Boolean(touched.email) && Boolean(errors.email)}
              helperText={touched.email && errors.email}
              sx={{ gridColumn: "span 4" }}
            />
            <TextField
              label="Password"
              type="password"
              onBlur={handleBlur}
              onChange={handleChange}
              value={values.password}
              name="password"
              error={Boolean(touched.password) && Boolean(errors.password)}
              helperText={touched.password && errors.password}
              sx={{ gridColumn: "span 4" }}
            />
            <TextField
              label="Confirm Password"
              type="password"
              onBlur={handleBlur}
              onChange={handleChange}
              value={values.confirmPassword}
              name="confirmPassword"
              error={
                Boolean(touched.confirmPassword) &&
                Boolean(errors.confirmPassword)
              }
              helperText={touched.confirmPassword && errors.confirmPassword}
              sx={{ gridColumn: "span 4" }}
            />
          </Box>
          {/* BUTTONS */}
          <Box>
            <Button
              type="submit"
              sx={{
                m: "2rem 0",
                p: "1rem",
                backgroundColor: palette.primary.main,
                color: palette.background.alt,
                "&:hover": { color: palette.primary.main }
              }}
            >
              {" "}
              REGISTER
            </Button>
            <Typography
              onClick={() => {
                navigate("/");
                resetForm();
              }}
              sx={{
                textDecoration: "underline",
                color: palette.primary.main,
                "&:hover": {
                  cursor: "pointer",
                  color: palette.primary.light
                }
              }}
            >
              Already have an account? Login here
            </Typography>
          </Box>
        </Form>
      )}
    </Formik>
  );
};

export default FormRegister;

Hope it helps

  • Related