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
})
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);
}
}
};