Home > OS >  Conditional useNavigate(), within button, based on error response
Conditional useNavigate(), within button, based on error response

Time:02-12

I have a signup form. Upon submit, if the inputs fail any validations, I need for the errors to be visible to the user, and for the browser to stay on the /signup page. If the form inputs pass all validations, I need for the submit button to navigate away to another page ('/about', as a placeholder).

The form submit button has an onSubmit(). At the end of the onSubmit I am calling the useNavigate hook to navigate away from /signup. I need something like a ternary which could, for example, say

errors ? null : navigate('/about)

"If there are errors, do not navigate, else navigate." I've tried many combinations but can't get it.

My full code:

import { React, useState } from 'react'
import './Signup.css'
import { useNavigate } from "react-router-dom";

export default function Signup() {

    const navigate = useNavigate()

    const [username, setUsername] = useState("");
    const [name, setName] = useState("");
    const [password, setPassword] = useState("");
    const [passwordConfirmation, setPasswordConfirmation] = useState("");
    const [errors, setErrors] = useState([])

    function onSubmit(e){
        e.preventDefault()
        const user = {
            name: name,
            username: username,
            password: password,
            password_confirmation: passwordConfirmation
        }
        fetch('http://localhost:3000/users', {
            method:'POST',
            headers:{'Content-Type': 'application/json'},
            body:JSON.stringify(user)
        })
        .then(res => res.json())
        .then(json => {
            if(json.errors) setErrors(Object.entries(json.errors))
        })
        // need something like a ternary which says,
        // if errors, stay on current page/render errors
        // else, navigate away
        navigate('/about')
    }


    return (
        <>
            <form onSubmit={onSubmit} className="form">
                {/* <div className="container1"> */}
                    <h3 className="login-h3">Sign ur ass uPPP</h3>
                    <input
                        type="text"
                        id="name"
                        placeholder="name"
                        value={name}
                        onChange={(e) => setName(e.target.value)}
                        />
                    <input 
                        type="text"
                        id="username"
                        placeholder="username" 
                        value={username}
                        onChange={(e) => setUsername(e.target.value)}
                        />
                    <input 
                        type="password"
                        id="password"
                        placeholder="password" 
                        value={password}
                        onChange={(e) => setPassword(e.target.value)}
                        />
                    <input 
                        type="password"
                        id="password_confirmation"
                        placeholder="confirm password" 
                        value={passwordConfirmation}
                        onChange={(e) => setPasswordConfirmation(e.target.value)}
                        />
                    <button 
                        
                        type="submit">Sign up!
                    </button>
                {/* </div> */}
            </form>
            { errors ? errors.map(e => <div>{e[0] ' : '   e[1]}</div>) : null}
        </>
    )
}

CodePudding user response:

You can use an if statement:

    function onSubmit(e){
    e.preventDefault()
    const user = {
        name: name,
        username: username,
        password: password,
        password_confirmation: passwordConfirmation
    }
    fetch('http://localhost:3000/users', {
        method:'POST',
        headers:{'Content-Type': 'application/json'},
        body:JSON.stringify(user)
    })
    .then(res => res.json())
    .then(json => {
        if(json.errors) setErrors(Object.entries(json.errors))
    })
    if(errors.length > 0){
     return null
    } else
    navigate('/about')
    }

This is using your errors state. If your setErrors recorded something it will set in the errors state.

CodePudding user response:

If you like, you can use

!errors && navigate('url')

Or you can configure your API return to generate error and use .catch, like that in your .then you can just follow the ok way.

  • Related