Search code examples
javascriptreactjsreact-reduxjsxredux-toolkit

react register errors not displaying


I am linking the front and the back of my web application and in the register part, I can't display the validation and server error messages to the UI. i am getting the 400 and 401 status when a wrong signup is performed
the message that i want to diplay is in Axsioserror>response>data>error

the probleme could be in the jsx rendring or in my reducer?

My component:

import React, { useState } from "react";
import { useDispatch } from "react-redux";
import "./Signup.css";
import Button from "../../components/ui/Button";
import { register } from "../../redux/reducers/authReducer";
import { useNavigate } from "react-router-dom";

const Signup = () => {
  const dispatch = useDispatch();
  const [username, setUsername] = useState("");
  const [email, setEmail] = useState("");
  const [errors, setErrors] = useState({});
  const [password, setPassword] = useState("");
  const navigate = useNavigate();

  const handleSubmit = async (e) => {
    e.preventDefault();
    const isValid = validateForm();
    if (!isValid) {
      navigate("/");
      return;
    }
    try {
      await dispatch(register({ username, email, password }));
    } catch (error) {
      if (error.response && error.response.data && error.response.data.error) {
        // Display error message to user
        setErrors({ message: error.response.data.error });
      } else {
        console.error(error);
      }
    }
  };
  

  const validateForm = () => {
    let errors = {};
    let isValid = true;

    // Validate email
    if (!email) {
      errors.email = "Email field is required";
      isValid = false;
    } else if (!/\S+@\S+\.\S+/.test(email)) {
      errors.email = "Email address is invalid";
      isValid = false;
    }

    // Validate password
    if (!password) {
      errors.password = "Password field is required";
      isValid = false;
    } else if (password.length < 6) {
      errors.password = "Password must be at least 6 characters long";
      isValid = false;
    }

    setErrors(errors);
    return isValid;
  };
  
  return (
    <div>
      <h2 className="register">Register :</h2>
      {errors.message && <span className="error">{errors.message}</span>}
    {errors.email && <span className="error">{errors.email}</span>}
    {errors.password && <span className="error">{errors.password}</span>}
      <form onSubmit={handleSubmit} className="signup-form">
        <input
          type="text"
          placeholder="User name"
          value={username}
          onChange={(event) => setUsername(event.target.value)}
        />
        <input
          type="email"
          placeholder="Email"
          value={email}
          onChange={(event) => setEmail(event.target.value)}
        />
        <input
          type="password"
          placeholder="Password"
          value={password}
          onChange={(event) => setPassword(event.target.value)}
        />
        <Button text="Submit" type="submit" submit />
      </form>
    </div>
  );
};

export default Signup; 

My Reducer:

 export const register = createAsyncThunk(
  "auth/register",
  async ({ username, email, password }, { rejectWithValue }) => {
    try {
      console.log("signup action creator called");
      const response = await axios.post(
        "http://localhost:5000/api/auth/register",
        { username, email, password }
      );
      console.log("signup response:", response);
      return response.data; // return the response data
    } catch (error) {
      console.log("signup error:", error);
      return rejectWithValue(error.response.data);
    }

  }
);

.addCase(signin.rejected, (state, action) => {
        state.loading = false;
        state.isAuthenticated = false;
        state.error =
          action.payload.error || "Failed to sign in. Please try again."; // set error message from response data, or fallback to a generic message
        toast.error(state.error); // display error message using React Toastify
      })

Solution

  • createAsyncThunk actions always resolve. If you want or care to know if the asynchronous action was successful or not then you'll want, or need, to unwrap the resolved Promise.

    See Handling Thunk Results for more details

    Example:

    const handleSubmit = async (e) => {
      e.preventDefault();
      const isValid = validateForm();
      if (!isValid) {
        navigate("/");
        return;
      }
      try {
        await dispatch(register({ username, email, password })).unwrap();
      } catch (error) {
        if (error.response && error.response.data && error.response.data.error) {
          // Display error message to user
          setErrors({ message: error.response.data.error });
        } else {
          console.error(error);
        }
      }
    };