javascriptreactjsnode.jsbootstrap-4user-accounts

How to show an alert based on console response? ReactJS


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.


Solution

  • 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 />
    ------