I have account registration on a website and I want the page to display an alert based on the success/failure to create the account.
Here's the current code I have (I have the alerts currently displayed at all times)
const isNotEmpty = (value) => value.trim() !== '';
const isEmail = (value) => value.includes('@');
function Register(props) {
const navigate = useNavigate()
//username input
const {
value: usernameValue,
isValid: usernameIsValid,
hasError: usernameHasError,
valueChangeHandler: usernameChangeHandler,
inputBlurHandler: usernameBlurHandler,
reset: resetUsername
} = useInput(isNotEmpty)
//password input
const {
value: passwordValue,
isValid: passwordIsValid,
hasError: passwordHasError,
valueChangeHandler: passwordChangeHandler,
inputBlurHandler: passwordBlurHandler,
reset: resetPassword
} = useInput(isNotEmpty)
//email input
const {
value: emailValue,
isValid: emailIsValid,
hasError: emailHasError,
valueChangeHandler: emailChangeHandler,
inputBlurHandler: emailBlurHandler,
reset: resetEmail
} = useInput(isEmail)
let formIsValid = false
if (usernameIsValid && emailIsValid && passwordIsValid) {
formIsValid = true
}
const submitHandler = async event => {
event.preventDefault()
const registerInput = {
username: usernameValue,
email: emailValue,
password: passwordValue
}
try {
const res = await axios.post("/api/auth/register", registerInput)
console.log(registerInput)
} catch (error) {
console.log(error.response?.data)
}
if (!formIsValid) return
resetEmail()
resetUsername()
resetPassword()
navigate()
}
const emailClasses = emailHasError ? 'form-control invalid' : 'form-control'
const usernameClasses = usernameHasError ? 'form-control invalid' : 'form-control'
const passwordClasses = passwordHasError ? 'form-control invalid' : 'form-control'
return (
<div className='centered'>
<form onSubmit={submitHandler} className='register-box'>
<h3 className="register-title">Create New Account</h3>
<div className='control-group'>
<div className={emailClasses}>
<input required
type="email"
name="email"
value={emailValue}
placeholder='Email'
onChange={emailChangeHandler}
onBlur={emailBlurHandler}
/>
{emailHasError && <p className="error-text">Please provide a valid Email</p>}
</div>
<div className={usernameClasses}>
<input required
type="text"
name="username"
value={usernameValue}
placeholder='Login ID'
onChange={usernameChangeHandler}
onBlur={usernameBlurHandler}
/>
{usernameHasError && <p className="error-text">Please enter your future Login ID</p>}
</div>
<div className={passwordClasses}>
<input required
type="password"
name="password"
value={passwordValue}
placeholder='Password'
onChange={passwordChangeHandler}
onBlur={passwordBlurHandler}
/>
{passwordHasError && <p className="error-text">Please enter your future Password</p>}
</div>
</div>
<Button disabled={!formIsValid}
onClick={alertClicked}
variant="primary"
type='submit'>
Create New Account
</Button>
<br></br>
<br></br>
<Alert variant="success">Account ceation was successful.</Alert>
<Alert variant="danger">Account creation has failed.</Alert>
</form>
</div>
)
}
export default Register
I have asked a similar question before and while I got an answer that temporarily solved the issue (which was by making two pages and redirect users to each page depending on the registration outcome) it is not quite what I'd like to have.
There are several ways to achieve this. You can add a timeout before navigating to the home page and show the alert based on the API response but that would not be a good experience for the user.
Instead you can use react-toastify library to show the success/error message in a more elegant way without letting the user wait. React-toastify would show the message on screen even when you are redirecting to another page. Here is the logic, you can customise the popup as per your requirement
Define a new function:
const showToast = (type, message) => {
if (type === "success") {
toast.success(message, {
position: "bottom-right",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: false,
pauseOnHover: false,
draggable: false,
});
} else {
toast.error(message, {
position: "bottom-right",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: false,
pauseOnHover: false,
draggable: false,
});
}
};
try {
const res = await axios.post("/api/auth/register", registerInput)
if(res.status === 200)
showToast("success", "Registration successful");
else
showToast("error", "There seems to be an Error during registration");
} catch (error) {
showToast("error", error.response?.data || "There seems to be an Error during registration");
}
P.S. Add <ToastContainer />
in the JSX at the top
return (
<div className='centered'>
<ToastContainer />
------