2

In my project I created a component that takes care of logins. It returns a form and contains a method for validation called onSubmit. Currently the method looks like this:

import { useState } from "react"

function Login({ onLogin }) {
    const [name, setName] = useState("")
    const [password, setPassword] = useState("")

    function onSubmit(e) {
        e.preventDefault()

        if (!name && !password) return alert("Please enter a username and a password!")
        if (!name) return alert("Please enter a username!")
        if (!password) return alert("Please enter a password!")

        onLogin({ name, password })

        setName("")
        setPassword("")
    }
}

I wanted to make the whole thing look better and switched the 3 if-statements with 2 ternary operators and one if-statement:

import { useState } from "react"

function Login({ onLogin }) {
    const [name, setName] = useState("")
    const [password, setPassword] = useState("")
    let missingData

    function onSubmit(e) {
        e.preventDefault()

        (!name && !password) ? missingData = "username and a password" : !name ? missingData = 
"username" : missingData = "password"
        if (!password || !name) return alert(`Please enter a ${missingData}!`)

        onLogin({ name, password })

        setName("")
        setPassword("")
    }
}

However, as soon as I try this, the following error occurs:

TypeError: e.preventDefault(...) is not a function

I have no idea how using a ternary here is affecting the event object. Especially since I have done it in a similar way in the Register component and no error occurred.

The return statement of the component, including the form, looks like this:

return (
    <>
        <h3>Login</h3>
        <form onSubmit={onSubmit}>
            <label>Username</label>
            <input
                type="text"
                placeholder="Username"
                value={name}
                onChange={(e) => setName(e.target.value)}
            />

            <label>Password</label>
            <input
                type="password"
                placeholder="Password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
            />

            <input type="submit" value="Login" />
        </form>
    </>
)
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75

1 Answers1

2

Since you are not using semicolons, JavaScript is having a hard time figuring out if the line containing e.preventDefault() has ended and is combining it with the next line.

You can fix this by adding a semicolon in one of two places:

function onSubmit(e) {
  e.preventDefault();
  ...

or

function onSubmit(e) {
  e.preventDefault()

  ;(!name && !password) ? missingData = "username and a password" : !name ? missingData = 
"username" : missingData = "password"
  ...

You can find a further explanation here, under "Starting a line with code that isn’t clearly a new statement": https://www.learnbasicjs.com/do-i-need-semicolons-in-javascript/

Ed Lucas
  • 5,955
  • 4
  • 30
  • 42